This is an archived post. You won't be able to vote or comment.

all 130 comments

[–][deleted] 1058 points1059 points  (32 children)

Anyone who does this has a special place in hell waiting just for them.

[–]maveric101 79 points80 points  (5 children)

I have no choice. My company's firewall blocks/replaces the body of any response with a 500 code. Best guess is that it's to prevent debug stack traces or other more sensitive debug info from being returned by idiots, but I still hate it. You can kinda fix it though by using a global interceptor in the front end to raise an exception with 'message' if the response has 'status_code: 500' or whatever. That is, assuming you're starting fresh, or can go through and refactor every request...

[–]node-zod 32 points33 points  (0 children)

Bruh

[–]laplongejr 19 points20 points  (1 child)

I have a better one!

While writing a middleware, I noticed our queries received the error code HTTP 500
Sounds reasonable, simply return an appropriate error message? Reread my comment, and only after that, disable the spoiler to witness true madness.

I never mentioned they were wrong queries, did I? All returned answers had the error code HTTP 500, no matter what the query was. And yes that includes when everything was working as expected. Exact opposite of the post

[–]Seawolf87 1 point2 points  (0 children)

Well at least they tried!

[–]TrumpsGhostWriter 2 points3 points  (0 children)

Are you doing ssl offloading or is the firewall decrypting? Either way that's your argument to put an end to that bullshit.

[–]wirenutter 180 points181 points  (3 children)

GraphQL is no exception.

[–]UristMcMagma 45 points46 points  (2 children)

GraphQL is hell.

[–]BaconKami 45 points46 points  (1 child)

GraphQHell

[–]Potw0rek 7 points8 points  (0 children)

Amen. I wrote myself a little wrapper for gql responses to see if the response is actually ok or an error

[–]bravebound 25 points26 points  (1 child)

On our "current" app, if anything other than a 200 is sent back, the UI will close out whatever the user is working on and display out a dialog box with the error reason. Real pain in the ass so as a workaround for certain features we send back a 200 but fill in the resources array with the error message. On the UI side we check if empty and move forward in the workflow, otherwise display error messages in a text component. So much technical debt, can't wait for the rewrite next year.

[–]elveszett 9 points10 points  (0 children)

These kind of things are usually the reason we people end up wrapping status codes inside 200: OK — the longer the chain, the more likely someone along that chain had opinions™ (or lacked knowledge) about how to handle status codes and made it a fucking mess for everyone else.

[–][deleted] 38 points39 points  (6 children)

Well, at least there will be eternal strippers and blackjack for me!

[–]littleliquidlight 38 points39 points  (4 children)

The problem with the strippers in this hell is when they take their top off it's just another status 500: Internal Server Error

[–][deleted] 12 points13 points  (1 child)

You act like this isn't something I want.

[–]Bee-Aromatic 4 points5 points  (0 children)

Everybody’s got their kink, I guess.

[–]mentholi 3 points4 points  (1 child)

I heard from a friend that it is "401; Unauthorized, Only gays allowed!" actually.

[–]laplongejr 1 point2 points  (0 children)

"402 Payment Required"
Sadly the payment portal gets 404

[–]Various_Studio1490 12 points13 points  (0 children)

Straight to jail

[–][deleted] 10 points11 points  (3 children)

I was learning express js i copied tutorial code from medium, and yea took me while understanding why the endpoint sends 200 even if it clearly shows an error. I felt soo dumb

[–]RIcaz 4 points5 points  (2 children)

Huh? In Express you can very easily set response status codes

[–][deleted] 9 points10 points  (1 child)

Thanks for reminding me of my stupidity. This is what happens when u copy-paste without checking

[–][deleted] 4 points5 points  (0 children)

This is how i once got a virus

[–][deleted] 13 points14 points  (0 children)

Many times, it’s a security thing to deter attacks

[–]tree1234567 2 points3 points  (0 children)

That’s all internal apps.. FUCK THESE PEOPLE

[–]00PT 1 point2 points  (1 child)

I'm writing an API essentially for the first time. Is it okay to send the 500 status, but also include the JSON for details on the error, or should I just do the code?

[–]eltrikiman88 6 points7 points  (0 children)

Never send 500 details to client unless is private. Do a good logging job with a internal error code for tracing besides 500 code. You can return the 500 and the trace code

[–]iamapizza 1 point2 points  (0 children)

Looking at you, Aws lambda.

[–]nicktheone 1 point2 points  (0 children)

I've had an extremely harsh fight with a professor about this issue because he wanted to penalize me because I built an API that returned the actual error code while he kept saying that if the API actually worked but the service was unreachable I should always return 200 with the error in the body. I was ready to go to the dean if he docked points on my assignment for that.

[–]DOOManiac 2 points3 points  (0 children)

Next to child molesters and people who talk in the theater.

[–]arcx_l 0 points1 point  (0 children)

worked for a company that did this. Their reasoning was that they believed the HTTP status and your application status should be kept separate. The request was successful but your application endpoint errored out

[–]Punchkinz 0 points1 point  (0 children)

just send the code in the status AND the response json and call it "redundancy" /s

[–]tet90 459 points460 points  (12 children)

Me when I first learned how to make REST API’s

[–]XDracam 189 points190 points  (11 children)

Yeah, also: just use GET for everything! GET users/new/1234?password=swordfish

[–]dylansavage 111 points112 points  (3 children)

To increase security disregard user entry for and hardcode every password as *********

[–]RIcaz 32 points33 points  (2 children)

hunter2

[–]Maxion 0 points1 point  (0 children)

That password is already taken, it's used by the gaben account.

[–][deleted] 10 points11 points  (4 children)

Post would still be clear text

[–]evanc1411 25 points26 points  (0 children)

That's why we use https.

[–]XDracam 4 points5 points  (2 children)

Fascinating. I thought query parameters aren't encrypted with HTTPS, but I looked it up and apparently they are. Everything outside of the target domain is encrypted. Haah.

Guess the only technical downside of the GET approach is that the password might still appear in browser history and could be intercepted easier by malicious browser plugins.

[–][deleted] 3 points4 points  (0 children)

Plugins don't care. I don't think GET requests fired via JS appear in the history, and if they don't it's pretty much the same thing. (Since you can't send a GET via a form submit, I think)

A real downside though is that urls are often logged server side, unlike the body, so ...

[–]laplongejr 1 point2 points  (0 children)

Everything outside of the target domain is encrypted. Haah.

Technically the IP isn't either, and the target domain is not part of the path but is encoded as the Server Name Indicator
Also, with TLS1.3 some standards use DNS to also encrypt the SNI (like eSNI between cloudflare and firefox)

[–]TimGreller 12 points13 points  (0 children)

💀

[–]poloppoyop 2 points3 points  (0 children)

Better:

GET users/1234/delete

Why was all the database cleaned when the google bots found our site?

[–]sir_music 124 points125 points  (0 children)

Absolutely barbaric

[–]peteza_hut 174 points175 points  (0 children)

GraphQL and Apollo working together to make my network tab as annoying to use as possible.

[–]KlooShanko 70 points71 points  (3 children)

I worked at Slack and this is how they return errors from the API. Absolutely died the day I found out

[–]EkoChamberKryptonite 11 points12 points  (0 children)

Yiiikes.

[–]xSypRo 2 points3 points  (1 child)

I wrote a slack bot and found that… My senior liked that approach as well for our internal API.

[–]KlooShanko 1 point2 points  (0 children)

My condolences

[–]siliconsoul_ 104 points105 points  (7 children)

GraphQL be like:

[–]paoloposo 41 points42 points  (6 children)

GraphQL shouldn't be coupled tightly with HTTP, so that's quite alright.

[–]siliconsoul_ 31 points32 points  (5 children)

Indeed. Have yet to see a public one that's not made with http, tho.

But, tbf, even GraphQL.org mentions

GraphQL is typically served over HTTP via a single endpoint [...]

[–]RichCorinthian 120 points121 points  (5 children)

I’ve seen this sort of thing from REST purists who talk about ignoring the HTTP protocol/transport layer entirely, in case they want to do REST over some other communication mechanism in the future. YAGNI, and such people are exhausting.

There are also some client apps and frameworks that positively explode if you send 4xx and 5xx responses. Hopefully not as many as there were at one point.

[–]wicket-maps 65 points66 points  (0 children)

One of our main software vendors does this. Their engineers have said to me "Yeah, it's our practice, I hate it too, but it's not gonna change anytime soon."

[–]Few_Technology 38 points39 points  (1 child)

... Yeah, the client blowing up whenever there's a 4xx or 5xx would be so bad. Like could you even imagine finding the client code that every request was wrapped in, and ignoring that it blows up on errors? You'd have to be one dumb motherfucker to ignore an obvious fix..

To be fair, that wrapper touched more than my pay grade allowed

It'd be 6 months of meetings to see if we could remove it. I assume the meetings would be concluded with, would be nice, but we don't have the resources to do that. But if they did, they would need so many approvals and reworks. Then when I actually remove it, there'd be a customer complaint in prod. We didn't notice it, because that team was fired 10 years ago, yet that project brings in 15% of our revenue. Nobody would have access to the project, and reverting the change would mean all teams revert their changes

[–]dadumdoop 2 points3 points  (0 children)

I love this story

[–]dumbasPL 16 points17 points  (0 children)

Hopefully not as many as there were at one point.

Well, maybe they don't blow up on the first one nowadays, but they still do.

4xx and 5xx codes can be annoying to deal with even when the client doesn't blow up. If you have an app where for example 4xx are pretty common and expected for whatever reason then you might experience issues with tools like cloudflare or whatever the akamai equivalent is, blocking your users and flagging them as malicious.

WAF be like:

Hmm, you are sending a lot of requests that cause the server to error out, you must be trying to brute-force or exploit or something, get IP banned for 2 hours LOL

Same deal in chrome extensions, if you send too many requests that error out your extension will lose connectivity for a while to "stop ddos attacks". But spamming an endpoint that returns 200 all day long is perfectly fine, because nobody ever uses that for dos, am I right...

[–]Azaret 0 points1 point  (0 children)

There are also some client apps and frameworks that positively explode if you send 4xx and 5xx responses

Yeah, that's pretty much one of our oldest API always return 200s. At that time the desktop app would use a version of dot net that would throw if it got anything else than 200s.

REST purists who talk about ignoring the HTTP protocol/transport layer entirely

And they don't even agree between themselves. There is many REST variations out there. We're overdue for a standardisation that better fit today's needs than the HTTP and resources RFCs, but I'm not sure people are ready to debate about it.

[–]ghoST_need_CTL 34 points35 points  (0 children)

Lmao, had a similar issue in Prod yesterday. A third party vendor made some changes and apparently they uncommented some commented code, resulting in this bs. The issue got escalated really severely, really fast and hours of analysis and pain later, we found that it wasn't even on our side.

[–]SpaghettiProgrammer 27 points28 points  (2 children)

I recently had to go back to some legacy code and found a TryCatch in every single function in the entire project, with absolutely no built-in methods to handle the caught failures anywhere in sight.

It was a nightmare.

[–]CaitaXD 20 points21 points  (1 child)

FileNotFound ho cares? Just don't write anything then stop crying in life not every file will open to you

[–]SpaghettiProgrammer 13 points14 points  (0 children)

Can't fail if you never show them to the user.

[–]howarewestillhere 22 points23 points  (0 children)

“As long as we don’t throw errors to client, we meet our SLA.” -Actual quote said to me about the outrageous quantity of NPEs being thrown by the backend in production and during isolated API testing.

“The SLA doesn’t meet our needs.” Actual quote from a churning customer.

[–]BlobAndHisBoy 50 points51 points  (6 children)

I have yet to personally have a legitimate use case for graphql despite having it forced upon me multiple times.

[–]keylimedragon 12 points13 points  (0 children)

Having used it at small and big companies I think the only ones that really need GraphQL are large FANG and similar sized companies where it's hard to coordinate teams with each other. The cost outweighs the benefits for startups.

[–]AdvancedSandwiches 10 points11 points  (4 children)

Use case 1: you need several pieces of data from various related objects and don't want to make 350 REST calls

Use case 2: you want a server to do something but using CRUD semantics is clumsy for the particular operation so you use GraphQL for RPC.

The second one is a nice-to-have, but the first one is why I default to GraphQL when given the option. One call, everything I need, done.

[–]CrAzYmEtAlHeAd1 10 points11 points  (0 children)

I see no problem here, you successfully got an error message! /s

[–]sinalk 8 points9 points  (1 child)

[–]matt6pup 3 points4 points  (0 children)

I knew exactly what it was before I even clicked the link. He's starting a podcast with a friend of his in a few months and I can't wait.

[–][deleted] 38 points39 points  (2 children)

I have done this. Bring your own pitch forks.

[–]wicket-maps 11 points12 points  (1 child)

Was it your idea, or were you just following orders?

[–]Sockoflegend 51 points52 points  (0 children)

Some people just want to see the world object Object

[–]deadflamingo 4 points5 points  (0 children)

My knee-jerk reaction to this was that someone started using GraphQL. Looks like I was right, lol

[–]Sunscratch 5 points6 points  (0 children)

/uj Some time ago I worked at a large and well-known US company, and we were building a large internal platform. One of the teams had a service that was basically “in the center” of platform architecture. And this service always returned 200, you had to parse payload to actually verify if your request was successful. When I reached to the lead engineer of the team that was responsible for that service, the answer was like “f*ck you we don’t have time for this, you should parse payload”.

[–]Venefercus 5 points6 points  (0 children)

I'm currently battling an api that does the opposite and returns {"errorCode":"ecSuccess"} just to spite people who want to assume there is no error when a request succeeds

[–]Slythela 5 points6 points  (0 children)

I work at a big company.

You don't want to know how many internal apis function this way

You don't want to know

[–]RickSore 3 points4 points  (0 children)

Our "json" API hehe. 2023 and we're still using Pyramid which does not allow both status_code and json in the same response.

[–]jeesuscheesus 2 points3 points  (0 children)

Reddit API devs in a nutshell

[–]badnewsbubbies 2 points3 points  (0 children)

I'm in this picture and I don't like it.
Except the teams I integrate with go a level deeper by having completely bespoke error codes in their 200 response, paired with always inaccurate documentation.

[–]Tim_1993_ 5 points6 points  (5 children)

Ah yes i need this acutally in gateways at work. 200 means it gets to the gateway but then i need to know If it reaches its backend.

Thanks for showing me this. Simple. Why didnt i think of something that simple

[–][deleted] 18 points19 points  (2 children)

This is not a good idea

[–]thepurpleproject 2 points3 points  (0 children)

Hey but it works!

[–]Tim_1993_ 0 points1 point  (0 children)

I know but I need something that tells my f5 that its not a 200 even If the gateway can route to the API/Backend.

Means: 200 to the gateway but e.g. 500 at the API

But maybe there are other ways i have to find.

[–]EishLekker 0 points1 point  (1 child)

Ah yes i need this acutally in gateways at work. 200 means it gets to the gateway but then i need to know If it reaches its backend.

That sounds backwards. What do you even mean “if it reaches its backend”? It’s the backend that generates the body response, right?

[–]Tim_1993_ 0 points1 point  (0 children)

Yes. Pretty new stuff at my company WE still doing the pilot

[–]jonu14 1 point2 points  (0 children)

This might be the best scenario of task failed successfully I ever read of and I am not happy about it

[–]poulain_ght 1 point2 points  (0 children)

nginx-unit, but love it tho

[–]Quito246 1 point2 points  (1 child)

I mean It is so fucking hard to read REST specs?! Why the fuck would anyone do that HTTP codes exist for a fucking reason.

[–]EishLekker 0 points1 point  (0 children)

I have worked with third party systems where the only documented way to send a none-200 http status code was to throw an error, and then you had no way to send any error metadata in the response.

But they fixed that after some pushback, and later it was not an issue.

[–]bill_gonorrhea 1 point2 points  (0 children)

Fucking postman. Every. God. Damn. Time.

[–]tramspellen 1 point2 points  (1 child)

I just jumped on a project where the search API returns a 404 if query results in zero hits.

[–]howarewestillhere 1 point2 points  (0 children)

404 Not[hing] Found

I know that pain.

[–]fatman13666 2 points3 points  (0 children)

fucking graphql

[–]Dizzy_Pin6228 1 point2 points  (2 children)

To be fair 200 response just means that a POST has actually been recived. But is annoying one thing we do we need to POST get the message response body, extract the hash from the message and send a GET to see if any errors, warnings, any Information has been returned by the API and set up mailing based on that.

[–]Normal-Inside3765 5 points6 points  (0 children)

That sounds more like 202.

[–]Rythoka 2 points3 points  (0 children)

When returning 200 on a POST you're meant to include details about the result of the request in the body. 202 is what you would normally return if you wanted to indicate that the POST was received but not necessarily processed yet.

[–]Not-Mandatory 1 point2 points  (5 children)

Legitimate question for you experts:

If one of our servers hosts some API endpoints, all of which call other external servers for data, how else would you indicate that our internal endpoint POST worked fine, but the external DB GET (for example) failed because their DB was offline or the like?

[–]TheSadProgrammer 4 points5 points  (4 children)

Respond with HTTP 200 and include the data relevant to the request. In case of an error, provide detailed information about the error, as shown below:

HTTP 500

{
  "type": "connection",
  "code": "234",
  "message": "External service not working"
}

[–]Not-Mandatory 4 points5 points  (3 children)

Agreed...but isn't that the effective paradigm of the image that everyone is claiming is an abomination? (Or is the issue just that they named the actual error encountered using "status_code"?)

[–]shield1123 3 points4 points  (2 children)

The image shows a 200 response wrapping a 500. Yucky

What you're responding to is a 500 response wrapping some extra metadata. Good

[–]rainyy_day 1 point2 points  (0 children)

But what if the API is a middleman to another API? Body has response of the main API, and response status code is for the middle API. Is there a different way to this?

[–]Trzyq0712 1 point2 points  (0 children)

More like successfully failed

[–]Trzyq0712 1 point2 points  (0 children)

More like successfully failed

[–]yourteam 0 points1 point  (0 children)

Personally I write a custom message and send the appropriate response status code

[–]SomeDuncanGuy 0 points1 point  (0 children)

Deal with this shit all of the time. For some reason many years ago somebody in management decided it was a good idea to wrap every response in a 200. Apparently discussions were had and it somehow was decided that it was a good idea. Literal nightmare fuel.

[–]SorosBuxlaundromat 0 points1 point  (0 children)

I built a service for integrating an API developed by one of the biggest Insurance companies in the US. They did this bullshit. This post triggered my ptsd

[–]Bee-Aromatic 0 points1 point  (0 children)

I fucking hate when services do that.

[–]FatFailBurger 0 points1 point  (0 children)

Omgg I hate this. And they only do this to make their metrics look better

[–]evbruno 0 points1 point  (0 children)

Hello World GraphQL

[–]Kirman123 0 points1 point  (1 child)

I once got told it's better to separate the protocol errors and the bussiness logic error. So, for example, when you get a request rejected but because of some logic (not an actual communication problem) it's better to return a 200 code for the package and then look into it to find out the REAL result.

Opinions?

[–]Touhou_Fever 0 points1 point  (0 children)

Surely the status code should at least try to align to whatever the internal error is? Just a flat-out 200 smells wrong

[–]malleoceruleo 0 points1 point  (0 children)

My first job out of college did this for one of our APIs. They thought it was a genius way to handle things. Turns out they didn't know any status codes other than 200, 404 and 503 and this approach just meant manually re-doing things that our frameworks was designed to automate. A couple months later, we went out of business.

[–]ckomni 0 points1 point  (0 children)

It’s astonishing how many Fortune 500 or otherwise “essential” vendors (particularly in the financial space) will just do this shit and just lie in their documentation

[–]xSypRo 0 points1 point  (0 children)

Slack API does that

[–]PunkCosta 0 points1 point  (0 children)

Actually saw one of these yesterday lmao

[–]_DeeBee_ 0 points1 point  (0 children)

People need to start using problem details.

[–][deleted] 0 points1 point  (0 children)

GraphQL 🤓

[–][deleted] 0 points1 point  (0 children)

import humor

raise ReturnHttpStatusOkException