• renzev@lemmy.world
    link
    fedilink
    arrow-up
    1
    arrow-down
    1
    ·
    20 hours ago

    This is a good practice tho. The HTTP code describes the status of the HTTP operation. Did the server handle it? No? Was the url not found? Did it time out? Was the payload too large? And the JSON describes the result of the backend operation. So 200 OK with error: true means that your HTTP request was all good, but the actual operation bugged out for whatever reason. If you try to indicate errors in the backend with a HTTP error code, you quickly get confused about which codes can happen for what reason.

  • RizzoTheSmall@lemm.ee
    link
    fedilink
    English
    arrow-up
    75
    ·
    6 days ago

    I know an architect who designs APIs this way. Also includes a status code in the response object because why have one status code when you can have two, potentially contradictory, status codes?

    • boonhet@lemm.ee
      link
      fedilink
      arrow-up
      50
      ·
      6 days ago

      I inherited a project where it was essentially impossible to get anything other than 200 OK. Trying to use a private endpoint without logging in? 200 OK unauthorized. Sent gibberish instead of actual request body format? 200 OK bad request. Database connection down? You get the point…

    • ByteJunk@lemmy.world
      link
      fedilink
      arrow-up
      9
      ·
      edit-2
      5 days ago

      I may have run in your acquaintance work, stuff along the lines of

      200 OK

      { error_code: s23, error_msg: "An error was encountered when performing the operation" }

      If you happen to run into him, kindly tackle him in the groin for me.

      Thanks!

      • arendjr@programming.dev
        link
        fedilink
        arrow-up
        4
        arrow-down
        1
        ·
        edit-2
        5 days ago

        Well, looking at your example, I think a good case can even be made for it.

        “s23” doesn’t look like an HTTP status code, so including it can make total sense. After all, there’s plenty of reasons why you could want custom error codes that don’t really align with HTTP codes, and customised error messages are also a sensible use case for that.

        Of course duplicating the actual HTTP status code in your body is just silly. And if you use custom error codes, it often still makes sense to use the closest matching HTTP status code in addition to it (so yeah, I agree the 200 in your example doesn’t make a lot of sense). But neither of those preclude good reasons for custom codes.

        • Opisek@lemmy.world
          link
          fedilink
          arrow-up
          4
          ·
          5 days ago

          Still, 200 should not be returned. If you have your own codes, just return 500 alongside that custom code.

        • ByteJunk@lemmy.world
          link
          fedilink
          arrow-up
          1
          ·
          5 days ago

          But WHY are you trying to make a case for a bad practice? Don’t enable this kind of bullshit, please.

          If there’s an error, don’t say it’s 200 OK. Give me something, a 4xx, or at least a 500. Sure, add all you want to the body, but respect the goddamn headers!

          This fucks up so many things - starting right with API specs and documentation, s23 (or any other code this crap spits out) are not a part of the pdf file, which is the ONLY available documentation for this 3rd party service. If it serves any internal purpose, I have no clue, but for me it’s useless.

          Log analytics is a mess, and you can forget about auto-generating a client, of course…

          This is just a huge red flag for me, if their public interfaces look like this, I dont want to know whats under the hood, and I’m actively lobbying for us to change to another provider.

          • arendjr@programming.dev
            link
            fedilink
            arrow-up
            1
            ·
            5 days ago

            I’m making a case for custom codes, not for using a 200 status code with it. My reply said the 200 didn’t make sense.

            Of course once you use custom codes, the actual HTTP status codes do become less important, because there’s some redundancy there. That’s not an argument to do it wrong, but it is an argument that accurate HTTP status codes are less of a priority. So understandably some people will take shortcuts.

            Apparently you find this very frustrating, but in the end it’s just an implementation detail. But it also sounds like you’re more frustrated with the service API as a whole than the fact it uses custom error codes specifically, so I’m just going to leave it at that.

      • letsgo@lemm.ee
        link
        fedilink
        English
        arrow-up
        6
        ·
        6 days ago

        When I used to work at Oracle every so often a customer would call and complain some function was throwing error “ORA-00000 normal successful completion” and they wanted it filing as a bug and for us to fix it.

        I was never quite sure how we were supposed to fix stupid.

    • jballs@sh.itjust.works
      link
      fedilink
      English
      arrow-up
      6
      ·
      6 days ago

      Ugh this just reminded me that I ran into this exact issue a couple years ago. We were running jobs every hour to ingest data from an API into our data warehouse. Eventually we got reports from users about having gaps in our data. We dug into it for days trying to find a pattern, but couldn’t pinpoint anything. We were just missing random pieces of data, but our jobs never reported any failures.

      Eventually we were able to determine the issue. HTTP 200 with “error: true” in the response. Fml

    • paequ2@lemmy.today
      link
      fedilink
      English
      arrow-up
      6
      ·
      6 days ago

      I’ve seen the status code in a JSON response before: https://cloud.google.com/storage/docs/json_api/v1/status-codes#401-unauthorized

      One reason I can think of for including it is that it may make it easier for the consumer to check the status code if it’s in the JSON. Depending on how many layers of abstraction you have, your app may not have access to the raw HTTP response.

      Although, yeah you lose the single source of truth though.

      • zalgotext@sh.itjust.works
        link
        fedilink
        arrow-up
        7
        ·
        6 days ago

        Depending on how many layers of abstraction you have, your app may not have access to the raw HTTP response.

        That sounds like either over-abstraction or bad abstraction then

        • Takumidesh@lemmy.world
          link
          fedilink
          arrow-up
          3
          ·
          edit-2
          5 days ago

          Yea, I don’t really see a scenario where you are both, making http requests (and therefore care about http responses), and also not able to see the response.

          If you are using some wrapper client for an API, you wouldn’t be dealing with the response anyway so it being in json isn’t particularly helpful

  • Blackmist@feddit.uk
    link
    fedilink
    English
    arrow-up
    27
    ·
    5 days ago

    Ah, the 200 Go Fuck Yourself pattern.

    I use HTTP error codes in my API, and still occasionally see a GET /resource/{“error”:“invalid branchID provided”} from people who don’t seem to know what they are.

    • andrefsp@lemmy.world
      link
      fedilink
      arrow-up
      10
      ·
      edit-2
      6 days ago

      I had a similar one at a past work too. A test which was asserting a response status 500.

      Like, instead of the test asserting the correct error/status code was being returned, it was instead asserting any error would simply getting masked as a 500.

      Basically, asserting the code was buggy…

      That made me angry a couple of times but I still miss that place sometimes.

  • CrackedLinuxISO@lemmy.dbzer0.com
    link
    fedilink
    English
    arrow-up
    29
    ·
    edit-2
    6 days ago

    At a prior job, our API load balancers would swallow all errors and return an HTTP 200 response with no content. It was because we had one or two clients with shitty integrations that couldn’t handle anything but 200. Of course, they brought in enough money that we couldn’t ever force them to fix it on their end.

    • herrvogel@lemmy.world
      link
      fedilink
      arrow-up
      28
      ·
      6 days ago

      I once worked on a project where the main function would run the entire code in a try-catch block. The catch block did nothing. Just returned 200 OK. Didn’t even log the error anywhere. Never seen anything so incredibly frustrating to work on.

      • CrackedLinuxISO@lemmy.dbzer0.com
        link
        fedilink
        English
        arrow-up
        5
        ·
        6 days ago

        There was nothing RESTful or well planned about this API’s interfaces, and the work to do something like that would have been nontrivial. Management never prioritized the work.

      • tiredofsametab@fedia.io
        link
        fedilink
        arrow-up
        2
        ·
        5 days ago

        Assuming there was some API key system in place, could just check on the key to see if it belongs to one of those clients. If yes, 200. Else, real APIs.

    • Donnywholovedbowling@lemmy.world
      link
      fedilink
      arrow-up
      8
      ·
      6 days ago

      My team recently migrated to graphql and they don’t even do it right. The graphql layer still makes REST calls and then translates them to a gql format, so not only do we get no time or computing savings, we also get the bullshit errors

    • lunarul@lemmy.world
      link
      fedilink
      arrow-up
      5
      ·
      edit-2
      6 days ago

      It make sense for a wrapper layer to do this and I had to fight against APIs that didn’t. If I make a single HTTP call that wraps multiple independent API calls into one, then the overall HTTP code should reflect status of the wrapper service, and the individual responses should each have their own code as returned by the underlying services.

      For example on one app we needed to get user names by user id for a bunch of users. To optimize this, we batched calls into groups. The API would fail with an error code if one of the user ids in the batch was bad or couldn’t be found. That meant we wouldn’t be getting data for any of the users in the batch and we didn’t know which userId was bad either. Such a call should return 200 for the overall call and individual result for each id, some of which could be errors.

    • tiredofsametab@fedia.io
      link
      fedilink
      arrow-up
      2
      ·
      5 days ago

      I looked into it once at my last company, but none of us knew it and we had a tight deadline. For our scale and usecase, it definitely seemed like needless complication for most things compared to any payoff of switching.

  • jol@discuss.tchncs.de
    link
    fedilink
    arrow-up
    17
    ·
    6 days ago

    Several Favicon APIs do this. Even Google’s Favicon endpoint does it, because they return a fallback image. It’s pretty annoying.

  • madcaesar@lemmy.world
    link
    fedilink
    arrow-up
    13
    arrow-down
    2
    ·
    6 days ago

    Here I am preferring 200, with success boolean / message string…

    Iike HTTP errors codes for real fuck up’s, if I see 500 somethings fucked in the app, otherwise a standardised json response body seems way easier

    • fuzzzerd@programming.dev
      link
      fedilink
      English
      arrow-up
      20
      ·
      6 days ago

      What about both? User supplies bad input? HTTP 400 with response body json describing the error in a standard format?

        • dan@upvote.au
          link
          fedilink
          arrow-up
          5
          ·
          5 days ago

          Throwing exceptions is fine since errors are an exceptional circumstance (not expected during normal use of the app), and you probably want errors to follow a different code path so that they can be logged, alerts triggered if needed, etc.

  • HeyThisIsntTheYMCA@lemmy.world
    link
    fedilink
    English
    arrow-up
    7
    ·
    6 days ago

    I always loved how Sierra took its error message and turned it into an intentionally quitting the game message because every time they closed the game, instead of closing properly it crashed.

  • Shanmugha@lemmy.world
    link
    fedilink
    arrow-up
    9
    arrow-down
    1
    ·
    6 days ago

    I’ve got better news:

    • notice 200 error:true story on our side
    • fix it
    • fix it better: add detailed description, add message on what needs to be done on client side

    Client to mutual users: meh, we see an error, not our problem. Me: screams in swear language

  • tiredofsametab@fedia.io
    link
    fedilink
    arrow-up
    3
    ·
    5 days ago

    me with gRPC error codes: nil, parameter error, app error – OK, you fucked up, we fucked up. Edit: forgot NotFound.

    I really should read about the various ones that exist at some point, but I’ve always got bigger fires to put out.

    Edit, since it seems unclear, gRPC != HTTP and does not use the same status codes. I meant that I felt like I was using fewer than I should, though I just checked and basically not.

    • dan@upvote.au
      link
      fedilink
      arrow-up
      9
      ·
      5 days ago

      This is basically the difference between HTTP 4xx and 5xx error codes. 4xx means the client did something wrong (invalid request, tried to load something that doesn’t exist, doesn’t have access), whereas 5xx means the request was OK but something broke on the server.

      • tiredofsametab@fedia.io
        link
        fedilink
        arrow-up
        3
        ·
        5 days ago

        Yeah, I know how http status codes work. I just followed the existing pattern at my current place with gRPC and this post made me realize I don’t know most gRPC error codes and best practices.

          • tiredofsametab@fedia.io
            link
            fedilink
            arrow-up
            1
            ·
            5 days ago

            gRPC does not use HTTP status codes. I meant that I might be making a similar mistake with gRPC status codes though, after checking just now, not so much (there are only 17 total codes, not all of which apply to my APIs).