Well no, the HTTP error codes are about the entire request, not just whether or not the actual header part was received and processed right.
Like HTTP 403, HTTP only has a basic form of authentication built in, anything else needs the server to handle it externally (e.g. via session cookies). It wouldn’t make sense to send “HTTP 200” in response to trying to access a resource without being logged in just because the request was well formed.
Many GraphQL and gRPC APIs do exactly that and return HTTP 200 even if the request didn’t auth.
Just because you are heavily biased toward using HTTP status for application layer errors doesn’t make it right. It is so wildly common that people can’t imagine it working another way, and I get that.
But it’s not “wrong” to do application layer auth status codes and apply no transport layer auth status codes It’s just a different paradigm than most devs are used to.
Think the point would be that it’s super easy to also set a ‘non-ok’ status in HTTP. Sure it may be insufficient for sophisticated handling, but at least you can get a vague sense of ‘something went wrong’…
Sure have your more specific API specific error code and your error details in the body, but at least toss a generic ‘500’ into the status code. I often find myself writing client software where I don’t need specific handling I just need to know ‘it failed’, and it’s obnoxious to deal with these interfaces where I have to sweat multiple potential ways for it to report failures when I just don’t care about the specifics. Sometimes an API doesn’t even have a consistent place that it sticks it’s return code, some don’t even define a reasonable way to know ‘failure’ and require you to explicitly map a huge number of ‘info’ to ascertain if it’s normal or error type state.
Ehh, that really feel like “But other people do it wrong too” to me, half the 4xx error codes are application layer errors for example (404 ain’t a transport layer error, neither is 403, 415, 422 or 451)
It also complicates actually processing the request as you’ve got to duplicate error handling between “request failed” and “request succeeded but actually failed”. My local cinema actually hits that error where their web frontend expects the backend to return errors, but the backend lies and says everything was successful, and then certain things break in the UI.
frontend expects the backend to return errors, but the backend lies and says everything was successful, and then certain things break in the UI
That’s a double failure then: not only does the backend do it wrong, the frontend devs don’t even know it. If they’d agreed on one way of handling it, they’d still be able to work it out. But if the devs don’t even communicate their standards with each other and the frontend devs obviously don’t know about the problem…
Yep, their frontend used a shared caller that would return the parsed JSON response if the request was successful, and error otherwise. And then the code that called it would use the returned object directly.
So I assume that most of the backend did actually surface error codes via the HTTP layer, it was just this one endpoint that didn’t (Which then broke the client side code when it tried to access non-existent properties of the response object), because otherwise basic testing would have caught it.
That’s also another reason to use the HTTP codes, by storing the error in the response body you now need extra code between the function doing the API call and the function handling a successful result, to examine the body to see if there was actually an error, all based on an ad-hoc per-endpoint format.
Well no, the HTTP error codes are about the entire request, not just whether or not the actual header part was received and processed right.
Like HTTP 403, HTTP only has a basic form of authentication built in, anything else needs the server to handle it externally (e.g. via session cookies). It wouldn’t make sense to send “HTTP 200” in response to trying to access a resource without being logged in just because the request was well formed.
Many GraphQL and gRPC APIs do exactly that and return HTTP 200 even if the request didn’t auth.
Just because you are heavily biased toward using HTTP status for application layer errors doesn’t make it right. It is so wildly common that people can’t imagine it working another way, and I get that.
But it’s not “wrong” to do application layer auth status codes and apply no transport layer auth status codes It’s just a different paradigm than most devs are used to.
Think the point would be that it’s super easy to also set a ‘non-ok’ status in HTTP. Sure it may be insufficient for sophisticated handling, but at least you can get a vague sense of ‘something went wrong’…
Sure have your more specific API specific error code and your error details in the body, but at least toss a generic ‘500’ into the status code. I often find myself writing client software where I don’t need specific handling I just need to know ‘it failed’, and it’s obnoxious to deal with these interfaces where I have to sweat multiple potential ways for it to report failures when I just don’t care about the specifics. Sometimes an API doesn’t even have a consistent place that it sticks it’s return code, some don’t even define a reasonable way to know ‘failure’ and require you to explicitly map a huge number of ‘info’ to ascertain if it’s normal or error type state.
Ehh, that really feel like “But other people do it wrong too” to me, half the 4xx error codes are application layer errors for example (404 ain’t a transport layer error, neither is 403, 415, 422 or 451)
It also complicates actually processing the request as you’ve got to duplicate error handling between “request failed” and “request succeeded but actually failed”. My local cinema actually hits that error where their web frontend expects the backend to return errors, but the backend lies and says everything was successful, and then certain things break in the UI.
That’s a double failure then: not only does the backend do it wrong, the frontend devs don’t even know it. If they’d agreed on one way of handling it, they’d still be able to work it out. But if the devs don’t even communicate their standards with each other and the frontend devs obviously don’t know about the problem…
Yep, their frontend used a shared caller that would return the parsed JSON response if the request was successful, and error otherwise. And then the code that called it would use the returned object directly.
So I assume that most of the backend did actually surface error codes via the HTTP layer, it was just this one endpoint that didn’t (Which then broke the client side code when it tried to access non-existent properties of the response object), because otherwise basic testing would have caught it.
That’s also another reason to use the HTTP codes, by storing the error in the response body you now need extra code between the function doing the API call and the function handling a successful result, to examine the body to see if there was actually an error, all based on an ad-hoc per-endpoint format.