You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by José Correia <me...@gmail.com> on 2022/06/03 10:05:09 UTC
[RFC] Implementing externally documented error codes across the Sling APIs
I would like to open the discussion on creating a standard for well-defined
and externally documented error codes in our APIs.
This simple approach is a very good way of keeping consistency on the
errors thrown by the API and improving error documentation, while also
simplifying the way that exceptions
that happen in lower-level modules of the system are handled by higher
modules such as servlet endpoints.
Stripe has a good example of good error code documentation:
https://stripe.com/docs/error-codes
*Pros:*
1. A single place of change for API error descriptions.
2. We can change the error descriptions without changing the error code,
which improves logging in the long term.
3. Can be extended to add links for the error code external
documentation. This could improve the API responses, providing more
feedback on errors.
4. Easier propagation of exception expected outcomes:
1. the expected description, error code, and HTTP status are
propagated easily inside the exceptions
2. This allows for the transport layer to be completely abstracted of
exceptions in lower modules, and simply act according to the error code
definition.
A PR was created implementing an initial approach in the Distribution Core
bundle:
https://github.com/apache/sling-org-apache-sling-distribution-core/pull/60
Comments are welcome!
Short example
*Error code definition:*
public enum ErrorCode {
/** * A generic unexpected error in the system. * Should
result in an INTERNAL_SERVER_ERROR HTTP status code. */
UNKNOWN_ERROR("unknown", "An unexpected error has occurred.", 500),
/** * Error that happens when the client tries to distribute a
package that exceeds the * configured package size limit. *
Should result in a BAD_REQUEST HTTP status code. */
DISTRIBUTION_PACKAGE_SIZE_LIMIT_EXCEEDED("package_limit_exceeded",
"Package has exceeded the" +
" limit bytes size.", 400);}
*Exceptions include this type as an additional property:*
public class DocumentedException extends Exception {
private ErrorCode errorCode;}
*Transport layer handles exception in an abstract way:*
try {
// execute logic} catch (Exception e) {
ErrorCode error = e.getErrorCode();
logger.error(error.getCode(), error.getDescription());
httpStatusCode = e.getHttpStatusCode();
-> return httpStatusCode and JSON containing description and code.}
Re: [RFC] Implementing externally documented error codes across the Sling APIs
Posted by Eric Norman <en...@apache.org>.
Hi,
Having a better way to correlate errors to additional information seems
like it could be useful.
I have a couple of questions to get discussion going:
1. Would this be per-bundle error codes and per-bundle documentation? Or
were you thinking that there would be some sharing or common error codes
that would need to be provided by some shared bundle? Can we ensure unique
error codes without some sort of namespace prefix on the errorCode?
2. Were you thinking that documentation would get auto-generated from
some tooling via the details in the enumeration source code or manually
maintained?
3. Since some of these seem to be errors that make it all the way back
to the end user (and not just logged) then would it make sense to have some
i18n support so the text can be translated to other languages?
4. It may not be possible for the thrower of the exception to know what
the http status code should be, perhaps that is a decision that is better
left to the code that catches the exception?
5. Do you have any thoughts on how this would impact the already
existing exceptions and error handling?
Regards,
Eric
On Fri, Jun 3, 2022 at 3:05 AM José Correia <me...@gmail.com> wrote:
> I would like to open the discussion on creating a standard for well-defined
> and externally documented error codes in our APIs.
>
> This simple approach is a very good way of keeping consistency on the
> errors thrown by the API and improving error documentation, while also
> simplifying the way that exceptions
> that happen in lower-level modules of the system are handled by higher
> modules such as servlet endpoints.
>
> Stripe has a good example of good error code documentation:
> https://stripe.com/docs/error-codes
>
> *Pros:*
>
> 1. A single place of change for API error descriptions.
> 2. We can change the error descriptions without changing the error code,
> which improves logging in the long term.
> 3. Can be extended to add links for the error code external
> documentation. This could improve the API responses, providing more
> feedback on errors.
> 4. Easier propagation of exception expected outcomes:
> 1. the expected description, error code, and HTTP status are
> propagated easily inside the exceptions
> 2. This allows for the transport layer to be completely abstracted of
> exceptions in lower modules, and simply act according to the error
> code
> definition.
>
>
> A PR was created implementing an initial approach in the Distribution Core
> bundle:
> https://github.com/apache/sling-org-apache-sling-distribution-core/pull/60
>
> Comments are welcome!
>
> Short example
>
> *Error code definition:*
>
> public enum ErrorCode {
> /** * A generic unexpected error in the system. * Should
> result in an INTERNAL_SERVER_ERROR HTTP status code. */
> UNKNOWN_ERROR("unknown", "An unexpected error has occurred.", 500),
> /** * Error that happens when the client tries to distribute a
> package that exceeds the * configured package size limit. *
> Should result in a BAD_REQUEST HTTP status code. */
> DISTRIBUTION_PACKAGE_SIZE_LIMIT_EXCEEDED("package_limit_exceeded",
> "Package has exceeded the" +
> " limit bytes size.", 400);}
>
>
> *Exceptions include this type as an additional property:*
>
> public class DocumentedException extends Exception {
>
> private ErrorCode errorCode;}
>
> *Transport layer handles exception in an abstract way:*
>
> try {
> // execute logic} catch (Exception e) {
> ErrorCode error = e.getErrorCode();
> logger.error(error.getCode(), error.getDescription());
>
> httpStatusCode = e.getHttpStatusCode();
> -> return httpStatusCode and JSON containing description and code.}
>