41
localpost
74d

Senior colleagues insisting on ALWAYS returning HTTP status 200 and sticking any error codes in the contained JSON response instead of using 4×× or 5×× statuses.

Bad input? Failed connections? Missing authorization? Doesn't matter, you get an OK. Wanna know if the request actually succeeded? Fuck you, parse potential kilobytes of JSON to get to the error code!

Am I the asshole or is that defeating the purpose of a status code?!

Comments
  • 7
    Application errors are not http errors.
    However, http errors are a widely accepted approach to throwing application errors back out as there is enough crossover.
  • 6
    @C0D4 I think it depends on the error. Then again, HTTP 5xx codes indicate an error was caused in the server side, so one could argue that all error responses generated by a web app that don't fit any other HTTP code (like a 404 for a nonexistent endpoint or 403/401 for authorization/authentication errors) should be sent at least as a 500 response.
  • 2
    @ethernetzero If the errors were asynchronous, I wouldn't mind a "202 Accepted" meaning the request may or may not succeed, but I'm specifically talking about an api that synchronously checks for authorization and body format and doesn't return a 401 or 400 respectively if they're missing/wrong
  • 5
    @localpost Yeah, I'm 100% with you. An application with a HTTP interface should respond with the appropriate HTTP codes for the kind of response it's sending. If the client is accessing an authenticated endpoint without having enough permissions, for example, return a 403. Your async response example is also a great one.
  • 2
    Any good explanation behind this request?

    HTTP Codes are there for a reason not to just throw 200 for everything and you figure out the rest, also for a login endpoint for example, why the need to return anything if server can just reply with 403 isn't it enough to tell the credentials are wrong?
  • 2
    Ask him what happens, if server is offline. Who will return 200 OK in that case? 😂
  • 2
    @WildOrangutan he'd probably expect my app to somehow know the server is down and not send the request in the first place.
  • 1
    Tell your crusty ass seniors to learn how to do modern development
  • 5
    Said it few times now.

    You're basically removing the easiest optimization that way...

    A status will always be received by a client.

    A payload will have to be manually fetched, most likely serialized (e.g. JSON)… and can only then be used.

    When you send a 403… you don't need to run the full enchilada, you know what has happened - way more efficient.

    Plus that in e.g. a load balancer you will not have easy access to a payload. E.g. in HAProxy, you have to preallocate a fixed buffer for it.

    This is for the same reason as any sane http client doesn't preload the response body - you don't know how large it is.
  • 2
    I think it depends on the type of error.

    If you have invalid credentials, yes, it's a 403 (or maybe 401).

    If the app code simply blew up, yes, should be a 500.

    If it's an invalid HTTP method, yes, should be a 405.

    But what if I send in a request to liquidate my checking account but the amount is greater than the balance? What HTTP code is appropriate then? Yes, you could make an argument for 400, or maybe 406, or MAYBE 409? You could argue for 451 even.

    But, I think the strongest argument is for 200, with some application-level error defined in the payload.

    The way I demarcate it is this:

    If the SERVER can determine the cause of the problem without application code even necessarily being involved, then an HTTP error code is usually appropriate.

    If it's something that is generated at the app code level, then a 200 - because the request WAS, effectively, "ok" - with an app-defined error in the payload doesn't hurt my head any.
  • 0
    @C0D4 excuse me?
    http errors are not errors in http, they are a way for the server to communicate errors to client. did you miss the rfc?
  • 6
    @fzammetti

    406 is absolute no-go, as it is an entirely different thing - Not acceptable means that the header content negotiation failed.

    409 is usually for a conflict regarding versioning.

    400 is usually the thing you want.

    https://developer.mozilla.org/en-US...

    https://httpwg.org/specs/...

    "The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error"

    Some argue strongly about the name "Bad Request" - but in general, every X00 code is "meant generally" as in "if nothing applies".

    In payment specific terms, 402 payment required would be a good choice, as it is more specific.

    In your example, the client made an unfulfillable request - the request cannot be done, it will abort due to non-sufficient funds.

    The 200 code would be imho only appropriate if the transaction (payment) could be done successfully.

    That's another thing maybe worth mentioning: Transactions.

    If an application has an transaction like state and the client request an transaction that cannot be done, replying to the request *creating* the transaction with 200 - OK... Is wrong?

    However, when a client requests to create a replication that cannot be done, replying with 400 - bad request (maybe better: unfulfillable request) makes more sense.

    I think that's the beautiful thing... Rest and HTTP codes can be mostly put in simple sentences.

    Last but not least: A 400 signals a "do not retry this request". While 200 status codes are - unless via headers explicitly stated - cacheable / repeatable.

    Another thing that one doesn't want in most cases when the request is not fulfillable.
  • 0
    http is so loosely defined that it‘s really up to you to define the contract. you could also just only allow the DELETE verb for everything and it would still be fine
  • 3
    Another reason why i won't do the always ok bs is: in some edge cases, bugs in the error handling of the backend, backend's server misconfiguration or such you aren't the one controlling the response. And it will be most likely one with error code 500 or what. So even if all your applikation layer errors are nicely wrapped in json shit, you will also habe a handling for those typws of errors in your frontend. So why not use the same error handling for both?
  • 0
    Promote them to interns.
Add Comment