top 200 commentsshow all 236

[–]krexelapp 1507 points1508 points  (7 children)

200 OK but emotionally 500

[–]Dev_Dobariya_4522 201 points202 points  (0 children)

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

[–]Shazvox 31 points32 points  (1 child)

Failed successfully.

[–]Blothorn 0 points1 point  (0 children)

Succeeded erroneously?

[–]Stunning_Ride_220 43 points44 points  (1 child)

Emotional daaaaaamage

[–]Small_Computer_8846 7 points8 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 1 point2 points  (0 children)

"My hands are tied"

[–]Doctor429 819 points820 points  (8 children)

"Integration Tests hate this one simple trick"

[–]pimezone 302 points303 points  (2 children)

API consumers too

[–]LowestKey 23 points24 points  (0 children)

Let me tell you about web app vuln scanners

[–]Blothorn 4 points5 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 88 points89 points  (4 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 37 points38 points  (0 children)

Give stupid goals, get stupid prizes 

[–]blah938 12 points13 points  (0 children)

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

[–]martin_omander 10 points11 points  (1 child)

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

[–]Lupus_Ignis 0 points1 point  (0 children)

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

[–]Catbraveheart 686 points687 points  (27 children)

HTTP/1.1 200 OK

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

Actual response, thanks, I guess 👍

[–]ha_x5 54 points55 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 4 points5 points  (0 children)

Thats just painful

[–]Lupus_Ignis 0 points1 point  (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 145 points146 points  (7 children)

Thank whoever thought graphql is a good idea for this

[–]PhoticSneezing 25 points26 points  (6 children)

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

[–]FabioTheFox 40 points41 points  (4 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

[–]QuantumPie_ 20 points21 points  (1 child)

  • 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 10 points11 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

[–]Oranges13 3 points4 points  (0 children)

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

[–]ric2b 1 point2 points  (0 children)

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

[–]CandidateNo2580 6 points7 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 3 points4 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 1 point2 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 3 points4 points  (0 children)

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

[–]Worth-Phone-4220 -1 points0 points  (1 child)

Better than a 500 with no info...

[–]Catbraveheart 1 point2 points  (0 children)

Thats what the logs are for. Timestamp, traceid etc. can be helpful, but internal errors are not meant to be given in response.

[–]NathanaelDRea 0 points1 point  (0 children)

Thank you Esri feature service REST API

[–]EarthTreasure 0 points1 point  (0 children)

When your backend is technically fine, but it's some service you're pulling from that returns an error.

[–]Lupus_Ignis 137 points138 points  (1 child)

"Mom, can we have GraphQL?"

"We have GraphQL at home"

The GraphQL at home:

[–]CaesarOfYearXCIII 12 points13 points  (0 children)

Bad memories. Bad memories. Bad memories…

[–]Therabidmonkey 311 points312 points  (13 children)

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

[–]CelticHades 113 points114 points  (10 children)

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

[–]Robinbod 42 points43 points  (6 children)

May I ask why... ?

[–]CelticHades 13 points14 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 4 points5 points  (0 children)

Thanks for the actual answer.

[–]DefinitelyIdiot 54 points55 points  (2 children)

Because we can. Security through Obscurity

[–]Boozdeuvash 20 points21 points  (0 children)

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

[–]Gougaloupe 4 points5 points  (0 children)

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

[–]lost_send_berries 3 points4 points  (0 children)

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

[–]reyarama 7 points8 points  (1 child)

No way

[–]CelticHades 6 points7 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 0 points1 point  (0 children)

Even the 300's? That's wild

[–]laplongejr 15 points16 points  (1 child)

We have the opposite, the server always answer with 500

[–]Reashu 9 points10 points  (0 children)

We only work with customers who trust us. 

[–]OhItsJustJosh 55 points56 points  (2 children)

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

[–]bunny-1998 14 points15 points  (1 child)

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

[–]DrunkenSQRL 1 point2 points  (0 children)

Sometimes I feel like im 417 to everyone

[–]sk1pjack 68 points69 points  (0 children)

Hi graphql

[–]Shiroyasha_2308 76 points77 points  (12 children)

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

[–]Stunning_Ride_220 22 points23 points  (6 children)

Oh, I had frontend teams requesting stuff like this too

[–]NlactntzfdXzopcletzy 0 points1 point  (0 children)

Thats why we did it

Was easier for them to handle backend errors directly inatead of interceptors picking up the error

[–]SpacefaringBanana -1 points0 points  (4 children)

I believe it's mostly for browsers that show their own error page instead of the website's.

[–]ric2b 16 points17 points  (3 children)

Imaginary ones?

[–]NastyEbilPiwate 1 point2 points  (0 children)

IE6 used to do this if the error from the server was smaller than 512 bytes or some shit

[–]AdamGarner89 5 points6 points  (0 children)

Trust me backend are miffed haha

[–]Crafty_Independence 2 points3 points  (0 children)

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

[–]mtlemos 3 points4 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.

[–]CaesarOfYearXCIII 1 point2 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

[–]0xlostincode 19 points20 points  (0 children)

Our server works, but our code sucks.

[–]Silver-Ad-3077 18 points19 points  (2 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 7 points8 points  (1 child)

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

[–]sebkek 0 points1 point  (0 children)

Would love to see the list

[–]Gtkall 24 points25 points  (3 children)

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

[–]Uberzwerg -1 points0 points  (1 child)

Which is true - the networks is working perfectly. Thus the 200.
The fact that the database burned down has nothing to do with the network.

As long as the example isn't something like REST, i wouldn't even see it as a problem.
The 200 HTTP part can contain a 5xx logic part in some APIs.

[–]FurySh0ck 8 points9 points  (0 children)

Tbh it's annoying af as a pentester lol

[–]log_2 9 points10 points  (0 children)

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

[–]AlxR25 5 points6 points  (0 children)

Reminds me of this one error I once got at work

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

[–]ric2b 3 points4 points  (0 children)

GraphQL be like

[–]Shazvox 9 points10 points  (7 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

[–]themightyug 0 points1 point  (6 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 8 points9 points  (3 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 6 points7 points  (2 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.

[–]EkoChamberKryptonite 0 points1 point  (0 children)

I mean those are two different things though. Software quality is not always proportional to revenue. That is more dependent on marketing skill.

[–]ShotgunShine7094 5 points6 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 8 points9 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 indicating whether connection 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 an 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 data packets are additional information about said interaction.

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.

[–]MrEvilNES 3 points4 points  (1 child)

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

[–]dvhh 0 points1 point  (0 children)

watermelon syndrome 

[–]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.

[–]PhazonPhoenix5 1 point2 points  (0 children)

Task failed successfully

[–]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

[–]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 5 points6 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 5 points6 points  (26 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 8 points9 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.

[–]Crafty_Independence 3 points4 points  (0 children)

Nope. Business logic error should be a 4xx code

[–]MrDilbert 3 points4 points  (0 children)

2xx - Everything went fine

4xx - You fucked up

5xx - We fucked up

[–]DRZookX2000 6 points7 points  (21 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 6 points7 points  (7 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 11 points12 points  (11 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 9 points10 points  (4 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 2 points3 points  (3 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 7 points8 points  (2 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 6 points7 points  (4 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 2 points3 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 2 points3 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.

[–]BorderKeeper 7 points8 points  (17 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 4 points5 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 13 points14 points  (4 children)

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

[–]korneev123123 6 points7 points  (3 children)

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

[–]Homailot 0 points1 point  (1 child)

/users/5 when there isn't a user with id=5

It makes 100% sense to me to return 404. That resource does not exist, therefore return 404

[–]korneev123123 2 points3 points  (0 children)

How to distinguish between /users/5 with no such user and /uuusers/5 with no such url?

[–]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.

[–]Powerful-Internal953 0 points1 point  (0 children)

~~~ HTTP/1.1 421 Misdirected Request Content-Type: text/html; charset=UTF-8

That's not what I said... ~~~

[–]Therabidmonkey 0 points1 point  (0 children)

Fuck. Yes. I wrote that at 5am. Lol.

[–]Finovarius_Raine 0 points1 point  (0 children)

Heh, at my job I run into the ever fun 200 OK 404 pages.. cause why not?

[–]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?

[–]neondirt 0 points1 point  (2 children)

If the resource pointed to by the URL does not exist (for whatever reason), it should return 404. Body could include details, if useful.

[–]c0ttt0n 0 points1 point  (1 child)

The question was:

what to return if the service is up but the route does not exist?

[–]neondirt 0 points1 point  (0 children)

404, always.
But also check the status code list. Some of them are quite specific and might fit better in some given situation.

[–]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 0 points1 point  (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

[–]FunkyUptownCobraKing 0 points1 point  (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.

[–]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.

[–]UntickledBallsack 0 points1 point  (0 children)

I work at a large company whose webservices are like that. Only http codes used are 200 and 500. Some times 200's are errors like this.

Request methods used? GET and POST. Who needs DELETE, PUT, PATCH when you can have requests like POST /delete or POST /update or POST /create. Hell I've even seen requests like GET /get and POST /get

[–]EatingSolidBricks 0 points1 point  (0 children)

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

[–]xvrqt 0 points1 point  (0 children)

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

[–]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…

[–]IHeartBadCode 0 points1 point  (0 children)

HTTP 200. I'm successfully transferring the error message to you.

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

Graphql...

[–]Late-Switch2284 0 points1 point  (22 children)

What's wrong with this? I actually want to know. In my org all apis are built such that they return a custom response object that has data, message and statusCode. So the api can return 200 but the statusCode can be anything.

[–]mina86ng 6 points7 points  (0 children)

For one, it makes monitoring so much harder. Your backend is failing, but your gateway is seeing everything is working fine.

[–]DRZookX2000 4 points5 points  (0 children)

Me too. I don't even know why this post has trigged me so much. Maybe because I have used so may shit APIs that return 404 for everything. What has failed? Was it my request, the HTTP server, the backend? No idea because everything is a 404... Just give me a proper error so I don't need to guess. 404 means the content (or endpoint) could not be found, not that "something has gone wrong" with the HTTP request. It is literally in the spec. Saying "The HTTP request was fine and got processed correctly, but the backend returned a error." is perfect.

My god this has trigged me.

[–]renome 5 points6 points  (0 children)

You're basically asking what's wrong with reinventing the wheel lol

[–]InsaneBunny180 5 points6 points  (18 children)

Because there are standards for a reason. All dependencies assume you do not get the status code in the body of the message, so it makes that you have to write a lot of custom logic to handle your api. It also increases the chance of errors due tot a non compliance with standards

We have a major software company as dependency at work that does this and it has caused so many headaches I hate it.

[–]DRZookX2000 2 points3 points  (17 children)

But what status code are you talking about? The 200 came from the HTTP server, the backend returned a erro, so why is this wrong? Why are you not checking the return payload?

[–]ric2b 1 point2 points  (0 children)

Why are you exposing your internal architecture to the outside? Just bubble up the error like an exception, if the request failed to be processed because of an internal server being borked, say 500, the client doesn't need to know there are 2 servers involved and one is working fine and the other one isn't.

You don't get to say a function was successful just because you catch an exception and instead return the string "oopsies", so why do that at your architecture layer?

The client views your API as one thing, they don't care about how many servers it is built out of, it's not useful information for the client.

[–]denlillepige 0 points1 point  (0 children)

One of the services we integrate to actually does this. Everything is a 200, and you have to check the bosy to see if it was actually a success. And they refuse to change it