1

Lets say I have an API endpoint that executes some business operation which can result in many different failures that are not connected directly to the request.

The request is correctly formed and I cannot return 4xx failures, but the logic of the application dictates that I return different error messages.

Now I want the client to be able to differentiate these error messages so that different actions can be taken depending on the code. I can return a custom JSON like this e.g.

{
  "code": 15,
  "message": "Some business error has occurred"
}

Now the question is which HTTP status code should I use for such occasions if no standard code like Conflict or NotFound makes sense.

It seems that 500 InternalServerError is logical, but then how can I additionally flag that this cannot be retried, should it be just documented that given status codes is not possible to retry so one can retry if you don't get one of those?

Ilya Chernomordik
  • 27,817
  • 27
  • 121
  • 207
  • 1
    What makes you think that you can't use 4xx? Furthermore, have you seen ? – Julian Reschke Mar 11 '19 at 16:12
  • Aren't 4xx for malformed/invalid requests? If the request passes the validation but cannot be executed later, then it's one of 5xx I guess? – Ilya Chernomordik Mar 11 '19 at 16:16
  • 2
    I'm guessing that @JulianReschke is nudging you in the direction of a `422 Unprocessable Entity` response code (https://tools.ietf.org/html/rfc4918#section-11.2) with a body whose content-type is `application/problem+json`, but I don't want to put words in his mouth. – Eric Stein Mar 11 '19 at 18:10

1 Answers1

-4

Consult RFC 7231:

503 Service Unavailable looks like a potential candidate, but the RFC mentions that this is supposed to represent a problem "which will likely be alleviated after some delay." This would indicate to a client that it could try the same call later, maybe after business hours or on the weekend. This is not what you want.

501 Not Implemented could be possible, but the RFC mentions "This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource. A 501 response is cacheable by default;" This does not appear to be the case here - the HTTP method itself was presumably valid - the failure here seems to be happening at the business rules layer (e.g. sending in an account number that is not in the database), rather than an HTTP method (GET, POST, etc.) that you never got around to implementing.

That leaves the last serious candidate,

500 Internal Server Error

The 500 (Internal Server Error) status code indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.

This is the error code that is normally used for generic "an exception occurred in the app" situations. 500 is the best choice.

As to how to distinguish this from a "temporal internal trouble" error, you can include this as part of the HTTP body - just make sure that your client can parse out the custom codes!

Community
  • 1
  • 1
Robert Columbia
  • 6,313
  • 15
  • 32
  • 40
  • What is the best way to signal the "retryability" of the request additionally? Since it might not make sense to retry generally, but if it's some kind of temporal internal trouble, then it's fine. – Ilya Chernomordik Mar 11 '19 at 16:20
  • Given that Mr. Reschke is an author of the HTTP spec, I'd give his observation rather a lot of weight. – Eric Stein Mar 13 '19 at 13:56