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