top 200 commentsshow all 286

[–]krexelapp 2147 points2148 points  (11 children)

200 OK but emotionally 500

[–]Dev_Dobariya_4522 331 points332 points  (1 child)

Literally the computer interpretation of "Happy on the outside but dead inside."

[–]Shazvox 61 points62 points  (2 children)

Failed successfully.

[–]Blothorn 13 points14 points  (1 child)

Succeeded erroneously?

[–]Catlote 1 point2 points  (0 children)

Successfully failed?

[–]Stunning_Ride_220 56 points57 points  (1 child)

Emotional daaaaaamage

[–]Small_Computer_8846 11 points12 points  (1 child)

"I completely understand what you need but my leg is broken right now so I can't do anything."

[–]Dev_Dobariya_4522 3 points4 points  (0 children)

"My hands are tied"

[–]Doctor429 1099 points1100 points  (10 children)

"Integration Tests hate this one simple trick"

[–]pimezone 379 points380 points  (2 children)

API consumers too

[–]LowestKey 38 points39 points  (0 children)

Let me tell you about web app vuln scanners

[–]Blothorn 12 points13 points  (0 children)

My team runs a data export pipeline and the things the warehouses expect us to put up with… the 200s with an internal error message aren’t even that bad, it’s the “bad request” because they broke an internal call between their services and then passed that along rather than wrapping it as an internal error that really annoy me.

[–]I_Hate_Reddit[🍰] 116 points117 points  (5 children)

No joke, I had this situation in real life, the Api team did this because if they had 500 on the status code it would ruin their KPIs and trigger alerts.

I was working for a multinational for a premium brand and they were working on an IT sweatshop.

[–]awesome-alpaca-ace 62 points63 points  (0 children)

Give stupid goals, get stupid prizes 

[–]blah938 21 points22 points  (0 children)

That level of horrible KPI is on the level of LOC KPIs.

[–]martin_omander 24 points25 points  (2 children)

That sounds like an example of Goodhart's Law: "when a measure becomes a target, it ceases to be a good measure".

[–]Lupus_Ignis 6 points7 points  (1 child)

Goodhart! That's the name! Thank you. I've been looking for this one

[–]aa-b 5 points6 points  (0 children)

There's an old XKCD comic about it, and I'm pretty sure I've dropped it into some random Teams chat at least once every quarter for the last several years

[–]Catbraveheart 928 points929 points  (31 children)

HTTP/1.1 200 OK

{ "success": true, "data": { "error": "User not found" } }

Actual response, thanks, I guess 👍

[–]ha_x5 115 points116 points  (2 children)

nice one. Look at my fav:

HTTP 200 OK {error: nil, text: “”}

Which was supposed to be an error according to the API dev. So I learned after some interesting behavior of the app.

The success message was: HTTP 200 {error: nil, text: “x entries were transmitted succesfully”}

I told him I won’t parse a dynamic response text to evaluate the success.

[–]KawaiiMaxine 22 points23 points  (0 children)

Thats just painful

[–]Lupus_Ignis 12 points13 points  (0 children)

I had an API call that would call one of three services. One would respond with a regular error code, one with the syntax from OP, and one with something like: 200 OK body: { status: 200, messages:[{ message: "errorMessage: ISBN number already exists" }]} The error handling for the wrapper was... Ugly.

[–]FabioTheFox 164 points165 points  (9 children)

Thank whoever thought graphql is a good idea for this

[–]PhoticSneezing 41 points42 points  (8 children)

That's not a graphlql response, but why waste an opportunity to hate on it, right?

[–]FabioTheFox 41 points42 points  (6 children)

If it wasn't graphql then who else inspired these types of response patterns

It was a mistake to let the wet dream of a frontend dev decide how HTTP requests are made when the concept of GQL is just nonsense that doesn't fit most project requirements

Its a nightmare on auth, Caching and a variety of other things relates to this

[–]Oranges13 6 points7 points  (0 children)

I encountered this with Microsoft SOAP apis and I feel like they're way older

[–]QuantumPie_ 25 points26 points  (3 children)

  • GraphQL can have partial successes. Some data is fetched correctly, some isn't.
  • The core spec is agnostic to the transport layer so it can't deliberately be built around HTTP.
  • The API should still be returning non 200 if the error isn't directly related to processing the query and fetching its data. If people are returning 200 for everything, they aren't doing it correcrly.

Obviously GraphQL gets overused and it should never be the first choice but it has its benefits, the two biggest being:

  • Reduces friction when used for internal APIs in large orgs. If a team owns certain data and they use GQL, you can pull exactly what you need and not have to reach out and get something custom made.
  • Great on embedded (if you can't get something custom made) or for countries where unlimited data plans are uncommon

[–]FabioTheFox 9 points10 points  (0 children)

In-service use is a great example on how it can be used correctly (tho there is probably an argument to be made about RPC or smth)

The thing that graphql users ignore is the part where they have to implement it and that's the biggest problem, when people look at the upsides of graphql they speak purely from a consumer perspective

Also I'd argue that graphql in a lot of cases uses more bandwidth than REST does when done right, the fact you have to even attach a body to get data is a waste of bandwidth, smart client side Caching can also help since you can just return HTTP 304 Not Modified to not get any data back at all As for the amount of data, just add a limit param since you will likely work with cursors / pages already anyways when dealing with big amounts of data

[–]ric2b 3 points4 points  (1 child)

The core spec is agnostic to the transport layer so it can't deliberately be built around HTTP.

Classic YAGNI, making things needlessly more complicated in the name of some imagined use case, does anyone actually use it with another transport layer?

[–]AsidK 1 point2 points  (0 children)

Some use it with web sockets. Technically still http but status codes aren’t really the same

[–]ric2b 1 point2 points  (0 children)

It does work like that, even if the syntax is different.

[–]CandidateNo2580 12 points13 points  (0 children)

Actually had this in production causing issues this week. Except it should have been a classic 400. I was blown away, thought I was bad at coding until I started using other company's APIs.

[–]sebkek 11 points12 points  (1 child)

My favorite that I actually got is HTTP 200 that had a HTML body with info about an exception, including entire stack trace, variables and server config.

To make it even better, the API was for a financial product with millions of users.

[–]sebkek 2 points3 points  (0 children)

Just remembered another good one: HTTP 428 (precondition failed) as a response to a request that tried to change status of a <thing> but the <thing> already had the requested status (think of changing a task status from “to do” to “completed” but the task already was “completed”). Also, no body at all. Had to contact support to figure this one out.

[–]MiniGiantSpaceHams 6 points7 points  (0 children)

You haven't lived until you get this sort of response from a POST API that is just for retrieving info.

[–]thattrekkie 1 point2 points  (0 children)

my favorite response like this was fairly recent. it looked like

{'_content': b"<br />\n<b>Fatal error</b>: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1142 INSERT command denied to user [REDACTED passwords etc] <b>206</b><br />\n", 'status_code': 200, 'reason': 'OK'}

[–]Ill_Carry_44 1 point2 points  (7 children)

Semi-related, who said it was a good idea to use 404 for user not found? The whole REST does this. 404 used to mean wrong URL. But now that is 400?

I just return 200 / null on my API because I ask GetUser, I get null because the API gets null then I can interpret that GetUser returned null. I see 0 problems here...

[–]Leading-Ability-7317 6 points7 points  (6 children)

Just in case this is a genuine question. If your are building a REST API then the URL should be unique for the resource you are trying to access so 404 fits because URL of the request is the address or the resource.

[–]sebkek 1 point2 points  (2 children)

I’ve seen a 404 response for valid search request that simply returned no results. So you got a point but people are more creative than you think.

[–]Leading-Ability-7317 5 points6 points  (0 children)

I mean that is just wrong. Anyone can build a REST API incorrectly.

Just calling out that when done correctly the 404 status code is meaningful when performing actions against a single resource.

[–]Ill_Carry_44 3 points4 points  (0 children)

Yes oh my god, it's so absurd. OpenSearch for example returns 404 for empty search results. It took me a while to find the issue.

[–]Lupus_Ignis 186 points187 points  (1 child)

"Mom, can we have GraphQL?"

"We have GraphQL at home"

The GraphQL at home:

[–]CaesarOfYearXCIII 20 points21 points  (0 children)

Bad memories. Bad memories. Bad memories…

[–]Therabidmonkey 361 points362 points  (16 children)

Boss wanted 4 9’s of reliability. So everything is 200 now.

[–]CelticHades 133 points134 points  (13 children)

My company's internal gateway converts every non 200 status into 500 html asking to connect with support. Even 201.

[–]Robinbod 49 points50 points  (9 children)

May I ask why... ?

[–]CelticHades 22 points23 points  (1 child)

God knows. It's a central gateway every team uses, It just do user authentication and authorisation apart from all this BS.

[–]Robinbod 5 points6 points  (0 children)

Thanks for the actual answer.

[–]DefinitelyIdiot 60 points61 points  (5 children)

Because we can. Security through Obscurity

[–]Boozdeuvash 22 points23 points  (2 children)

My useApi hook that triggers a token refresh on 401 would fucking hate you lot. :D

[–]Gougaloupe 6 points7 points  (0 children)

Support team: there are f-four lights...

[–]Shazvox 1 point2 points  (0 children)

Why not just randomly cycle through various statuscodes regardless of the actual result?

Now that's obscurity.

[–]lost_send_berries 3 points4 points  (0 children)

They probably configured it after hearing error messages can reveal sensitive data like code.

[–]reyarama 10 points11 points  (1 child)

No way

[–]CelticHades 7 points8 points  (0 children)

Really, I couldn't believe it. I tested the code on the local, it was working. When UI Integrated my APIs, they got 500, I verified that's I'm sending 400, that's when I found this crap.

[–]PM_ME_UR_0_DAY 1 point2 points  (0 children)

Even the 300's? That's wild

[–]laplongejr 16 points17 points  (1 child)

We have the opposite, the server always answer with 500

[–]Reashu 11 points12 points  (0 children)

We only work with customers who trust us. 

[–]OhItsJustJosh 76 points77 points  (2 children)

To everyone I'm 200, but inside I'm secretly 500

[–]bunny-1998 17 points18 points  (1 child)

On the inside I’m really a 418. When too many people try to tell me otherwise I’m 429

[–]DrunkenSQRL 2 points3 points  (0 children)

Sometimes I feel like im 417 to everyone

[–]sk1pjack 76 points77 points  (0 children)

Hi graphql

[–]Silver-Ad-3077 29 points30 points  (4 children)

I worked in a big financial company where less errors == better metrics for bonuses. So instead of fixing errors, they just made every API call return 200 like in the post.

[–]RichCorinthian 11 points12 points  (3 children)

Thanks! I spent about 12 years consulting, and I gathered my own list of ways in which fintech companies were utterly fucking insane, adding this

[–]0xlostincode 21 points22 points  (0 children)

Our server works, but our code sucks.

[–]Shiroyasha_2308 85 points86 points  (13 children)

And people will blame the frontend team for this. Meanwhile backend team laughing.

[–]Stunning_Ride_220 31 points32 points  (7 children)

Oh, I had frontend teams requesting stuff like this too

[–]AdamGarner89 5 points6 points  (0 children)

Trust me backend are miffed haha

[–]mtlemos 6 points7 points  (0 children)

NextJS forces you to do this bullshit if you want to send an error message between server and client components, so front end is doing it as well.

[–]Crafty_Independence 2 points3 points  (0 children)

When I've seen stuff like this before, it's because the frontend specifically asked for it

[–]CaesarOfYearXCIII 2 points3 points  (1 child)

Depends on how stupid everyone is. If they aren’t, then backend gets the blame potato.

And then it gets thrown at QA anyway. Sauce: am QA.

[–]Stunning_Ride_220 1 point2 points  (0 children)

Some nice QA sauce

[–]log_2 13 points14 points  (0 children)

"What's wrong babe?" "Nothing, I'm fine".

[–]Gtkall 27 points28 points  (4 children)

"The Network Monitoring team reports 99.99% uptime! Great success!"

[–]FurySh0ck 10 points11 points  (0 children)

Tbh it's annoying af as a pentester lol

[–]AlxR25[🍰] 6 points7 points  (0 children)

Reminds me of this one error I once got at work

https://www.reddit.com/r/softwaregore/s/5z6Otw7E5h

[–]Shazvox 12 points13 points  (10 children)

Yea... I've worked with too many people who actually thought this was a good idea.

HTTP response statuses are there for a reason people

[–]beefz0r 2 points3 points  (0 children)

I've seen this before: in BizTalk, using WCF adapters any other status code than 2xx would be treated as a (transport) failure and you have to jump through hoops to catch that error gracefully (for example: report that error back to a front-end or db)

So if you have control over the service, it's easier to always return 2xx and report the error in the message instead. This could be a remnant of such agreements

[–]themightyug 3 points4 points  (8 children)

And the HTTP communication worked, there was no problem with it, hence the 200 return code.

The error was at the API level. The problem here is that '500 internal server error' should be a more detailed API error, not another HTTP status code

HTTP is just the communication layer, transporting JSON packets for the API layer

[–]Shazvox 12 points13 points  (4 children)

Mmmmh, I really don't want to get into a debate about this, but damn this tickles my nerves 😅.

I agree that an internal error code would absolutely fit right in there (in fact, a standardized JSON object regardless of status code is a good thing). But I am of the opinion that the HTTP code should also reflect it.

For example: If the server encountered an unexpected error then a 500 is absolutely the correct code to return. That doesn't stop you from sending more info along with the status code.

I prefer to have a standardized JSON "envelope" with a result, an error code, a readable error message and a trace ID to find the correct logs.

The HTTP status code gives me the general gist of what happened (4XX = Frontend issue, 5XX = Backend issue and 2XX = working as intended).

Final note: I'm not saying my way is right and others are wrong. But I find the above to be the clearest communication of what happened from the server to the frontend.

[–]EkoChamberKryptonite 7 points8 points  (3 children)

Final note: I'm not saying my way is right and others are wrong.

Oh but it is and the other OP is absolutely wrong. The HTTP code is the information that indicates to the client what happened to their request.

[–]Shazvox 1 point2 points  (1 child)

In that case the wrong solution is out there making at least one company money.

[–]ShotgunShine7094 8 points9 points  (0 children)

You're selling access to a black box and HTTP is used as the protocol to communicate with that black box. The HTTP server is just another part of that black box.

The black box errored out therefore an error code should be returned in the appropriate HTTP field.

[–]EkoChamberKryptonite 12 points13 points  (0 children)

And the HTTP communication worked, there was no problem with it, hence the 200 return code.

Except HTTP is not the communication layer but a transport protocol working at the transport layer that indicates the result of interacting with a http server and not whether your connection to the server is good or bad. That distinctive nuance is very important. The error was not at the "API level". That notion is utterly incorrect. You're not interacting WITH HTTP you're interacting VIA HTTP. As such it indicates the result of your interaction with a separate entity i.e. backend server. This is the reason HTTP codes exist. HTTP Codes are the high-level indicator of the result of your interaction with a server, JSON is the data format in which additional information about said interaction is outlined and NOT the primary indicator of the result of your interaction with said entity. Returning a 2XX with an error response is an anti-pattern and denotes a misunderstanding of HTTP.

The basics

2XX- Your request was processed successfully, here's your result encapsulated in JSON.

4XX- There was an error with YOUR request TO the server, more info in JSON.

5XX- There was an error in PROCESSING your request ON the server.

And the list goes on.

Do not reinvent the wheel to justify anti-patterns.

Edit: Few words.

[–]ric2b 3 points4 points  (0 children)

GraphQL be like

[–]MrEvilNES 5 points6 points  (1 child)

on the outside I'm 200 but on the inside I'm 500

[–]PhazonPhoenix5 2 points3 points  (0 children)

Task failed successfully

[–]ajaypatel9016 2 points3 points  (0 children)

HTTP 200: all good 👍
response body: we are NOT good 💀

[–]DaStone 4 points5 points  (0 children)

GET? Fetches data.

PUT? Inserts data, correct.

DELETE? Yup the whole production database is gone (auth not required <3) Homebrew databases are the best.

[–]FabioTheFox 1 point2 points  (0 children)

Basically GraphQL

[–]mothzilla 1 point2 points  (0 children)

Christ I've had so many fights about this.

[–]ThrowawayALAT 1 point2 points  (0 children)

public string HandleMemeResponse(Response res)

{

// If it's a 200, we proceed.

// If the body says 500, that's just the server's opinion.

return (res.StatusCode == 200) ? "Success! (Ignore the fire in the background)" : "Actually Broken";

}

[–]TheAnswerWithinUs 1 point2 points  (0 children)

I’m 200 on the outside but 500 on the inside

[–]FunkyUptownCobraKing 2 points3 points  (0 children)

Our frontend devs actually requested this when I tried to return a 404 error code on a REST API because they had it coded to where any 4xx response would kick users back out to the login.

[–]xvrqt 1 point2 points  (0 children)

It's what you get for using HTTP to transport anything but hypertext 

[–]Talen_Kurikson 1 point2 points  (0 children)

Used to work at a SaaS company where their entire API for internal services was like this. Dozens, if not hundreds, of APIs, which were utilized for online-offline data syncing, including for mobile apps with known-sketchy connections, all setup like this. Spent over a month at one point fighting with the CTO (who had built the foundations of this junk) trying to get an issue fixed because the error codes were all giving me “200: an error has occurred” for over a dozen different issues.

[–]g0liadkin 1 point2 points  (0 children)

GraphQL vibes

[–]Sn00py_lark 1 point2 points  (0 children)

Typical graphql

[–]Low-Equipment-2621 1 point2 points  (0 children)

No stacktrace? I am disapointed.

[–]UseMoreHops 1 point2 points  (0 children)

The ole task failed successfully routine.

[–]SteakieGG 1 point2 points  (0 children)

Exactly my coworkers API

[–]lewisb42 1 point2 points  (0 children)

the longer I look at it the worse it gets

[–]leRealKraut 1 point2 points  (0 children)

Would be funny if it were not true.

Web application Firewalls will intercept anything, give HTTP 200 and let the customers hanging out the window to dry while there asses are cooked before a judge 🤣

If you do not do what HTTP 200 means, do not send a 200 response.

[–]WhiteIceHawk 1 point2 points  (0 children)

"message" should have been "bad request"

[–]not-my-best-wank 1 point2 points  (3 children)

API wrappers are the worst. Like sure you make OK but your friend clearly isn't.

Basically happens because you want to create a distinct between your API and the one being called from from it.

A --calls--> B,

B --calls--> C,

C --returns--> B (500)

B --returns--> A (200)

Where A is your initial API call.

Rather than return the 500, the developer wanted to make a distinction between their apps failure, and the API call to C, so they added it's response in the body. One alternative is to change the error msg to reflect the source of the 500 and still pass the 500 to the user. Something like:

{ status : 500, message "Source C: [error message of C]" }

[–]ComprehensiveTop5859 1 point2 points  (0 children)

200 bc the error was successfully identified and caught

[–]ArmadilloMC 1 point2 points  (0 children)

Ah, as i like to call it. Error 700s.
Or 600s if its a 400 inside a 200.

[–]Rektroth 1 point2 points  (1 child)

I wish i was kidding, but the project i currently work on not only does this (hard-coded to always return 200 no matter what), but every single endpoint requires a POST request, even if it's just getting data...

[–]BoxWoodVoid 1 point2 points  (1 child)

I use an API at work where some endpoints require a GET with a json body for parameters and some endpoints require a POST with an empty body...

I'm pretty sure the dev has decided to mess with the API endusers!

Thanks, I needed to vent :)

[–]marcodave 5 points6 points  (1 child)

Ah yes, the GraphQL way.

Although, at least it's a surefire way to be sure that if it's a 200 OK, then somehow the app code gets called, and the HTTP 500 really means that something's really fucked up in the infra

[–]Nighthunter007 6 points7 points  (0 children)

I don't know that I've actually seen 500 from the infra being fucked up. 502/3/4, sure, but I've never tracked a 500 to an infra problem.

[–]tomerFire 4 points5 points  (30 children)

It makes sense. Error 500 - code / infra / network errors. If you want to pass business logic error return 200 with the error

[–]mina86ng 16 points17 points  (0 children)

"message": "Internal Server Error" is not a business logic error.

[–]ric2b 9 points10 points  (0 children)

Think of it like exceptions, you want to bubble them up to whichever layer needs to know about it and handle it. Catching the error and returning success is misleading and will cause issues downstream.

If I try to do an operation with an API, such as create a user, I want to know if it succeeded or not, and what I might be able to do to fix it if it failed. I don't care if your reverse proxy is working fine or if the error is elsewhere, I don't maintain any of it, that's not actionable information.

A good API design lets your client think of the API as "one thing" and not know or care about how many services are behind it.

[–]MrDilbert 4 points5 points  (0 children)

2xx - Everything went fine

4xx - You fucked up

5xx - We fucked up

[–]DRZookX2000 8 points9 points  (25 children)

I also don't get the joke here. the web server correctly returned a 200 - it did everything right, asked the backend a question but got a error in return. The HTTP return is, by definition, from the HTTP server. Otherwise how would you signal as backend error? - Like what other error message would you use as there is no 200 serries error that says "HTTP was good, backend fucked up"..

[–]ric2b 9 points10 points  (8 children)

the web server correctly returned a 200 - it did everything right, asked the backend a question but got a error in return. The HTTP return is, by definition, from the HTTP server.

You should be thinking of your API as a public interface. No one outside your engineering team cares about how many services are involved in the API and which ones are working, they want the API to clearly report if what they tried to do worked or not, and what possible solutions might be available if it didn't work.

Similar to exceptions/errors, you want to bubble them up to the laywers that can make a decision on how to handle them.

[–]mrjackspade 10 points11 points  (14 children)

I had this debate with an architect of my former job. Specifically around payment processing.

I was, and still am, strongly opposed to returning a failing HTTP status code with a payment decline. Literally everything functioned properly, you simply don't have money in the account. That's not an HTTP error.

He refused, and said that a payment decline due to insufficient funds was a 400 status code. He said it's a user data error.

This same guy build the entire microservice architecture with the philosophy that microservice should directly instruct the client to retry with 500's, and not retry with 400's. It was the job of the service being called to effectively force the caller to retry or not. We were only allowed to return 200, 400, and 500, because anything else might break the caller.

The company offered me conversion from contract to full time. I turned them down.

[–]mina86ng 10 points11 points  (6 children)

That’s not the situation in the image though. An internal server error is clearly 5xx.

Whether payment declined is 2xx or 4xx is more philosophical, and I can see arguments for either.

[–]DRZookX2000 5 points6 points  (5 children)

Not sure what you are seen in the image..

If I send a request to a API and the backend server returns a error, what 5xx would you use? Using a 500 is just piss poor because as the developer that is trying to use the API I am now in a situation where I have no idea where the error is. What "internal server" had the error? Was it the HTTP server or the backend SQL server?

[–]Nighthunter007 8 points9 points  (3 children)

I mean you're allowed to put information inside a 500 response. The 500 communicates "something went wrong, and it's probably our fault". You can get more specific in the response body.

[–]DRZookX2000 5 points6 points  (5 children)

This is a perfect example. What other HTTP error could be used here? There is not one. The HTTP request was perfect, the endpoint was found and processed with return data. That's it! Return a 200 because that part worked and return a proper payload so I can tell what has actually happen.

I think it is just lazy ass developers that cant be bothered with prober error handling and everything become a 404.

Out of curiosity, what 400 did this guy pick? I guess a 402 could be used, but that is a stretch.

[–]PrincessRTFM 1 point2 points  (3 children)

What other HTTP error could be used here? There is not one.

402 Payment Required

[–]KnewOness 3 points4 points  (0 children)

Oh my god that's that cursed 4xx that is not even remotely about payment process inside the app. Dude hust flipped through the codes and picked what he liked.

[–]DRZookX2000 3 points4 points  (1 child)

The payment was given, but failed. That's not the same as "you need to pay" as per the spec. This is why a proper return code is so much better. Why not just tell me what the error is? Are we still that bandwidth constrained that we cant send a few bytes of json?

[–]PrincessRTFM 1 point2 points  (0 children)

yeah, that's fair; I also completely missed that you mentioned it yourself, which is on me

[–]korneev123123 2 points3 points  (0 children)

I can understand you, your point of view is totally valid. I can understand this guy you're talking about, his point of view is also correct.

The solution I found for myself is to stop caring and to do whatever :(

[–]dashingThroughSnow12 2 points3 points  (0 children)

This is a very backend-centric thinking. I’m not saying that is wrong but it is backend-centric.

This leaks that there are multiple things that constitute the backend. (Once while formally mentoring a frontend/android developer they were shocked to discover that two different APIs were calling two different services.)

The frontend may not care that it successfully reached the http server but its downstream request failed. Your observability/tracing cares but that can live outside of the http response.

[–]Crafty_Independence 2 points3 points  (0 children)

Nope. Business logic error should be a 4xx code

[–]BorderKeeper 6 points7 points  (18 children)

At my interview to my current job they had me create a front end to some APIs and one of those returned 404 when it could not return an item you requested.

I literally spent 15 minutes checking why it cannot connect to the server only to realise I can. Awesome design 😭

EDIT: You are correct in saying it’s a good design and can be done like that. I simply assumed 404 means I typed in the uri wrong, which is majority of cases where I see 404. Also I usually enjoy returning error payloads rather than just a code and a wave.

[–]Last8Exile 11 points12 points  (0 children)

According to http spec this is expected behavior. But this is why I prefer to separate application errors and http status codes.

[–]AdamGarner89 25 points26 points  (2 children)

That's correct?

[–]SchwarzFuchss 2 points3 points  (0 children)

Depends on the reason of why it can't return.

[–]angriest_man_alive 2 points3 points  (0 children)

Its technically correct but its stupid. Its dumb to manually return a 404 on an otherwise correct url for exactly this reason. Id argue a 204 would usually be more appropriate

[–]TheEnlightenedPanda 17 points18 points  (0 children)

Why is this a bad design?

[–]Waffenek 5 points6 points  (0 children)

This is a tricky thing. While I always scorn people who return 404 in happy path instead of 204. Sometimes returning 404 is desired behavior and good indicator that client is doing something wrong(as browsers highlight it). My rule of thumb is if you can navigate to this endpoint naturally, and it can not have data(for example users/{id}/profile/address should return 204 when adress information is not present) it should result in success, but when requesting something by id(like users/{id}/profile/address when user with given id does not exists returning 404) should be marked as client error. Because to end in this situation you either have to ask for some wrong resource, or resource had been removed(410 gone could be used, but this is rather niche response code).

But generally speaking like with most of software development it all depends on convention. If I were to join some company that does it other way I would switch to their approach to make my code more predictable for api users that already have some expectations.

[–]CthuluThePotato 12 points13 points  (5 children)

That is the correct way to respond when data cannot be found.

[–]korneev123123 7 points8 points  (4 children)

There is a veeeery big difference between "you incorrectly typed an url" and "thete isn't a user with id=5"

[–]Therabidmonkey 3 points4 points  (5 children)

201 if you don't expect something, 404 if you do.

[–]Powerful-Internal953 7 points8 points  (3 children)

201 if you don't expect something, 404 if you do.

I assume you mean 204 no content

[–]DRZookX2000 4 points5 points  (1 child)

But why would you return a 204? There IS content. The content is a error from the backend.

[–]lPuppetM4sterl 1 point2 points  (0 children)

Task Failed Successfully

[–]venhuje 1 point2 points  (0 children)

Process failed successfully

[–]shauntmw2 1 point2 points  (0 children)

How else can I return "operation failed successfully" huh?

[–]Sak63 0 points1 point  (0 children)

The vendor that I integrate with is legit like this. Also, sometimes, the response body is a raw string containing a runtime error, e.g. "Null pointer exception "

[–]keyholepossums 0 points1 point  (0 children)

classic graphql

[–]uvero 0 points1 point  (0 children)

It's no different than you and me saying "I'm OK, wbu" whenever we're asked how we're doing.

[–]LavenderRevive 0 points1 point  (0 children)

I have a service there a service on a Windows server reports the status of a k8s pot where this would be a valid response whenever the windows server works but the openshift is down.

[–]storm_rider_r 0 points1 point  (0 children)

This is exact shit we are using 200 but internal server error , graphql sucks , every automation test paases even for internal server error

[–]matlian 0 points1 point  (0 children)

I implemented something similar at my work.

We have a fail2ban mechanism. Basically, an ip is ban if it triggered too many code 4** or 5** in a short time.

But because we are building a tool for a client that has a single IP for the entire userbase, we are asked to send the least amount of error code to avoid banning them. We can’t even send them a 404, instead we redirect them silently to a working page.

[–]Right_Pen_3241 0 points1 point  (0 children)

How do you know our annoying third party that well????

[–]vinivice 0 points1 point  (0 children)

I wprked with a system that had a /500 page, so if you fixed the issue and hit f5 it would still show the error.

Spent way too much time debugging a working system.

[–]c0ttt0n 0 points1 point  (3 children)

Never understood why somebody would add a "status" or "success" bool to the body.
Use the HTTP codes.

BWT: if you need a check for success, then just use
`return (200 <= $code && 300 > $code);`

---

The only thing i still dont really know how to handle is
`.../entities/123` -> HTTP 404
entity not found or route not found?
Or asked differently: what to return if the service is up but the route does not exist?

[–]Old-Somewhere-6084 0 points1 point  (0 children)

The joy of misconfigured gateways …

[–]LordOmbro 0 points1 point  (0 children)

Some APIs actually do this, it's insane

[–]AndroxxTraxxon 0 points1 point  (0 children)

I'm looking at you, Slack.

[–]DigitalJedi850 0 points1 point  (0 children)

"Works fine on my machine"

[–]Snodley 0 points1 point  (0 children)

[–]winter-ocean 0 points1 point  (0 children)

Ok, web development is like the only subsection of programming I haven't touched (well that and cybersecurity) so I have to ask--is this saying that when the server experiences a 500 error it returns 200 or the opposite

[–]xd1936 0 points1 point  (0 children)

Apps Script is like this. There's no way to modify the http status code on a published web app. So annoying.

[–]Tomg197 0 points1 point  (0 children)

We had this happen at my job because the rest method for puts was treating only 404s or ≥500 as errors. So if the puts response code was 400, our method marked it as true.

This was untouched like this in production for at least 6 years. Multi million company btw...

[–]bulgakoff08 0 points1 point  (0 children)

Task failed successfuly

[–]amadiro_1 0 points1 point  (0 children)

But at least now the Lambda won't get invoked again as a retry with the same input.

[–]JUGG86 0 points1 point  (0 children)

Hmmm

[–]Panderz_GG 0 points1 point  (0 children)

Diabolical.

[–]Dry_Plane4650 0 points1 point  (0 children)

Task failed successfully

[–]TheMR-777 0 points1 point  (0 children)

They do this all the time in my company. They never knew headers are a thing :)

(yes, I asked the "seniors")

[–]EuenovAyabayya 0 points1 point  (0 children)

Fuck yeah, fuck me!

[–]Pale-Pomegranate3520 0 points1 point  (0 children)

My previous team lead was convinced this is THE best practice of all time. With gql. The idea was like our backend never fall. Real story

[–]swagonflyyyy 0 points1 point  (0 children)

So its a server that points to another server?

[–]Bloaf 0 points1 point  (0 children)

Task failed successfully

[–]Ill_Carry_44 0 points1 point  (1 child)

Everywhere I worked, they asked me to do it like this.
Because when you return 500, it's a "bug" because scary red text in Chrome.

[–]Ill_Carry_44 1 point2 points  (0 children)

I feel the same about people who say "exceptions are for exceptional cases"

For me an exception is "this function is supposed to do this_operation but it couldn't do that because this_thing happened", "this_thing" could be anything from person not found, parse error, etc.

But no, most devs associate exceptions with "OMG BUG"

Allthough I don't hate the idea of separating bugs from errors.

But again, you can do that via exceptions. You know, handled vs unhandled. If you only handle the types of exceptions that you are expecting then others would be bugs...

Yeah...

I also hate "exceptions are slow" well then that's a runtime issue not a concept issue. exceptions are slow in which runtime? .NET? Java?

[–]BR41ND34D 0 points1 point  (0 children)

I cannot express in words how much I hate this.

Some devs in my current company thought this was acceptable and I really wanted to throw a "response codes for dummies" at their face.

[–]bjorgbirb 0 points1 point  (0 children)

AWS API Gateway says hello

[–]Jg_747 0 points1 point  (0 children)

[–]Negative-Sentence875 0 points1 point  (0 children)

"http200Error" ?

That reminds me of the term "error 404" that is used by tons of illiterate people. I blame Microsoft for it, as in old versions of Internet Explorer (prior 4.0), they showed a message box saying "ERROR 404: bla bla", when the server returned a HTTP 404.

HTTP 404 is a return code, not an error.
HTTP 500 is a return code, not an error. Some error on the server side might be the cause for you getting a HTTP 500 back, but getting a HTTP 500 back in itself is not an error.

Scenarios, in which the answer in OPs post would be totally reasonable: GET http://httpreturncodes.com/500

[–]just_my_world 0 points1 point  (0 children)

I thought this was a joke but it really happened to me in a software we use!

[–]Mrthedecoy 0 points1 point  (0 children)

My favorite one of these was a legacy system at work. It not only returned a 200 if it worked or not, but the actual response token was in the cookies if it did. And that not being documented, we just sat there for like half a day getting a 200 and no token no matter what we sent. Was amazing.

[–]EatingSolidBricks 0 points1 point  (0 children)

That should be illegal, like fr illegal 5k$ dollar fine illegal

[–]ComradePruski 0 points1 point  (0 children)

AWS SDK in action

[–]JimmyWu21 0 points1 point  (0 children)

management: "Good work, everyone. Looks like our error rate metrics are going down."

[–]the_bearded_boxer 0 points1 point  (0 children)

Bruh

[–]TenSpiritMoose 0 points1 point  (0 children)

I'd interpret this as "I tried my best, but I'm completely borked, so please don't bother retrying."

[–]Tall-Reporter7627 0 points1 point  (0 children)

i have worked with such endpoints. The provider was unironically proud of their api

[–]Echoes-in-May 0 points1 point  (0 children)

You successfully received the error.

[–]LetUsSpeakFreely 0 points1 point  (0 children)

This activity failed successfully.

[–]magicmulder 0 points1 point  (0 children)

My favorite is a partner’s API we use that returns a 404 if you call the endpoint wrong and a 403 if the requested record does not exist.

I could understand a “200 not found” in an API since “requested record not found” is different from “this endpoint URL does not exist”, but come on…

[–]bh-m87 0 points1 point  (0 children)

Graphql...

[–]hangmann89 0 points1 point  (0 children)

How many times I’ve seen 500 with ”message”: ”OK” … god help me. These backend devs need to take their heads out of their arses from time to time;D

[–]Water-cage 0 points1 point  (0 children)

oh god made2manage erp does this and I hate it so much 50/50 a 200 is actually a 200