Annoyingly, it depends on how meaningfully the issue (in the backend) is actually considered a problem (to the end user).
Just to prove the range of possibilities:
- If a main server failed, but the failover server worked, you'd likely not even tell the user that there is a problem.
- If your endpoint is supposed to find corroborating data from many external services, and one of those was not working, or you'd mention in passing that "service X could not be reached, but the request itself and thus is status code shouldn't indicate an error...
- unless there is an explicit requirement that the only way for a request to be considered successful is when all sources can corroborate it. Now, any absence of any external service will cause a negative HTTP status code to be returned.
It will gracefully handle the problem but needs to pass that information back to the requester (a JS front of mine, if that matters).
If by "gracefully handle" you mean that the actual request succeeds and the encountered issue is more of a "oh and by the way..." nature instead of a "this is the reason I couldn't do what you asked", then I agree that the HTTP status code should not indicate an error.
Another question tackled the issue for problems with the request (i.e. - the requester sent something that was not correct). My issue is likely different because the requester sent a correct request, but it was not honored by the API (it is the fault of the API).
The bolded parts are inherently orthogonal as far as HTTP status codes are concerned.
- 4xx status codes are errors which blame the sender of the request
- 5xx status code are errors in which the server blames itself
It helps to consider the meaning of these two different responses.
- 5xx errors mean that the server made a mistake somewhere. As an end user, you can likely expect that someone will fix the server at some point, and therefore you can eventually retry the same request.
- 4xx errors mean that the request you sent to the server is unusable. Either it violates some basic contract, it's not legible, or it refers to something that plain doesn't exist. In all of these cases, as an end user you are being told that retrying this same request is pointless.
These are broad strokes. Anyone can come up with a fringe exception whereby retrying coincidentally does/n't work, but that's beside the main point.
"it was not honored by the API" implies to me that the backend considers this a "dishonorable" request that the backend actively refuses to engage, therefore suggesting the error code belongs to the 4xx range.