> HTTP 200 OK
> look inside
> actually 401 Unauthorized wrapped in JSON for some reason

> DEBUG log level
> look inside
> error wrapped in JSON for some reason

(i just lost several hours to this)

edit: turns out it just looks bad but is actually reasonable-ish; see https://letsencrypt.org/2024/12/05/ending-ocsp https://github.com/caddyserver/caddy/issues/7023

@whitequark was this from atlassian software? Because I saw this behavior in atlassian software

@whitequark A couple jobs ago that was everything. Always HTTP 200, read your payload to see if something broke. Ugh.

Also always POST.

@whitequark Still trying to understand why the gold standard here at work is to serialize a json payload and insert it as a string into a json payload.

It makes our API schemas impossible to parse programmatically because it all dead ends at "data": string which tells you absolutely nothing.

@whitequark the frontend server successfully reported that access was refused to the backend server
@whitequark I actually got complaints from a colleague for returning HTTP errors instead of only reporting errors in JSON (of course the error response had a body with details). No, didn't change it it, they had to learn to live with it. ​
@malwareminigun @whitequark It's bad when API endpoints for state government services behave like that. More fun is 200 is successful but any and all errors or warnings return as 500 errors. 🥴
Oh, hey. It's GraphQL.

@tedward On one hand, GraphQL specification tried to be transport-neutral, so it doesn't specify what HTTP responses should people use when using GraphQL over HTTP. Also, since it allows multiple requests at once, how should it behave if just one request fail?

On the other hand, they should have standardized it. Like, I had issues with AniList's API due to that, if I try to optimize requests by using multiple requests (like fetching user data and show data at the same time) and one fails (like if the show or user doesn't exist), the entire request fails (in their implementation).

@qgustavor FWIW I’ve had this happen before, and it was because the API in question defined the return type as non-nullable. To support partial responses, return types must be nullable so that GQL can insert a null where the data would go, and then put a corresponding error for that null in the errors array.

A GQL implementation might rightly be unable to give you a schema-compliant partial response to your query in that case, so it has to fail the whole response.

@NfNitLoop Hey, I asked help from people from AniList on GitHub almost six years ago! https://web.archive.org/web/20200919063914/https://github.com/AniList/ApiV2-GraphQL-Docs/issues/52

Thank you for this answer!

That being said, I don't think that's the answer to this issue, unless I misread documentation on nullable fields.

All queries fail when one fails · Issue #52 · AniList/ApiV2-GraphQL-Docs

It's similar to this issue: when doing multiple queries and some fails it returns 404 and null on all fields. As an example here's a simplified GraphQL query, the variables and the returned...

GitHub
@qgustavor ah, yep, that sounds like a bug in that implementation!
@malwareminigun @whitequark I do a lot of work with load balancers, this made me unreasonably angry.

Since this is blowing up: If anyone knows the original author of this I'd love to make sure they're credited somehow. I spent maybe 20 minutes trying to find the original before posting but gave up after finding nothing but a million reposts.

Of course I didn't exactly help the situation but enough people here seem to be happy about it that they're one of today's lucky 10000

@malwareminigun
The original original is probably this one, but I don't know who did the HTTP 200 variant first, sorry :(
https://pbfcomics.com/comics/quiz-kid/
Quiz Kid

The Perry Bible Fellowship

The Perry Bible Fellowship
@malwareminigun @whitequark I still can't believe HTTP has dedicated, usually unambiguous status codes indicating failure states and actual websites don't even use them properly

@iagondiscord I mean... given that there was a whole 'hey maybe we should actually use what's in the HTTP protocol" that got a while name / movement 'REST' I guess we shouldn't be that surprised.

At the end of the day it didn't matter what the details of the HTTP protocol were. What matters is that it's the protocol browser speak, and the same content page served with a 2XX code vs. a 4XX code is not a meaningful user facing difference.

@whitequark is it GraphQL? 🙈😆
@whitequark I don't know why people do this

@whitequark

[like]
look inside
actually seething hatred and sympathy

@whitequark shades of NVMe-MI admin command error handling. Not sure if specifying it is better or worse. I guess it should at least be expected.
@whitequark This happens when people use too much SOAP.
@whitequark I've seen this in SAP Fiori
@whitequark who ever decided this was a thing has a special place in hell

@whitequark things that kill me as a QA with a strong API focus.

It’s the type of thing that makes me wanna throw rocks through windows

@whitequark happened to me with spring boot, don't remember what I did wrong. But was completely unintentional. So if you don't test errors, this is the outcome.
@whitequark this breaks so many things downstream, and also makes your friendly neighbourhood ops people unfriendly.
@whitequark I smell graphql 😵‍💫
@whitequark I call that "not supporting HTTP" because that's what it is
@whitequark I have a very faint memory of that being a thing around 15y ago and it had to do either with some browsers either not accepting empty body replies with 202s (and maybe 200s) or some ajax bs with some bigger framework and so it was actually not too uncommon. Unless this is some ancient unmaintained stuff (and my memory not completely failing) it's probably just normal jank or incompetence though.
@whitequark isn't it a bit early for horror stories? It's not October yet.
@whitequark I once had to use a SOAP API that in the XML response has a single field and that single field contained JSON response.
@whitequark i’ve seen it in a couple of places. Mostly because management was pushing to deliver ‘green’ dashboards. Vanity metrics FTW!
@whitequark Don't forget the reverse proxy in front of this that turns any real 4xx or 5xx into a gateway error for some reason
@whitequark it's called 'web boolean'.
200 - anything
500 - anything the devs didn't test
@whitequark
I once read that this could have something to do with old enterprise proxies, what would replace any non-2xx response with some generic company error page
@whitequark
Are you by any chance describing my heroics implementing an event driven Shopware5 connection some years ago?