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.}

Reply via email to