question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Queries returning only errors are forced to be a 500

See original GitHub issue

On commit b3ccce9 a query response containing only the errors field is forced to be a 500, however these errors could easily be coercion errors due to incorrect input types, thus a bad request and not a server error. I am wondering if there is a strong opinion to keep it this way or if we could improve this logic and potentially make it configurable? A lot of client code that makes graphQL requests often retry on 500 errors and in the case of coercion errors will never succeed.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:26
  • Comments:37 (9 by maintainers)

github_iconTop GitHub Comments

6reactions
berstendcommented, Jan 4, 2019

Hardcoded 5xx errors made me a little sad, as this might confuse certain GraphQL clients.

This PR doesn’t seem to be exhaustive or about to be merged and I also didn’t feel like maintaining a fork.

I therefore resorted to the next best thing, hijacking the express send handler. 🐴

import { NextFunction, Request, Response } from "express";
import * as hijackResponse from "hijackresponse";

// Extend Express Response with hijack specific function
interface IHijackedResponse extends Response {
  unhijack: () => void;
}

/**
 * Stupid problems sometimes require stupid solutions.
 * Unfortunately `express-graphql` has hardcoded 4xx/5xx http status codes in certain error scenarios.
 * In addition they also finalize the response, so no other middleware shall prevail in their wake.
 *
 * It's best practice to always return 200 in GraphQL APIs and specify the error in the response,
 * as otherwise clients might choke on the response or unnecessarily retry stuff.
 * Also monitoring is improved by only throwing 5xx responses on unexpected server errors.
 *
 * This middleware will hijack the `res.send` method which gives us one last chance to modify
 * the response and normalize the response status codes.
 *
 * The only alternative to this would be to either fork or ditch `express-graphql`. ;-)
 */
export const responseHijack = (_: Request, originalRes: Response, next: NextFunction) => {
  hijackResponse(originalRes, (err: Error, res: IHijackedResponse) => {
    // In case we encounter a "real" non GraphQL server error we keep it untouched and move on.
    if (err) {
      res.unhijack();
      return next(err);
    }

    // We like our status code simple in GraphQL land
    // e.g. Apollo clients will retry on 5xx despite potentially not necessary.
    res.statusCode = 200;
    res.pipe(res);
  });
  // next() must be called explicitly, even when hijacking the response:
  next();
};

Usage:

import { responseHijack } from "./expressMiddleware/responseHijack";
app.use(responseHijack);

Please note: My inline comment is not meant to be snarky or condescending, I appreciate all open source work ❤️

5reactions
proehlencommented, Jan 23, 2021

@acao Since pull request #696 has been reverted in #736, can this issue be re-opened? I could log a new issue but the discussion here is useful history.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Error handling - Apollo GraphQL Docs
If Apollo Server hasn't correctly started up or is in the process of shutting down, it responds with a 500 status code. The...
Read more >
How to Fix a 500 Internal Server Error on Your WordPress Site
The 500 Internal Server Error status code occurs when the server encounters an error that prevents it from fulfilling the request.
Read more >
Catching a 500 server error in Flask - python - Stack Overflow
I want to catch Python errors when something goes wrong an exception is raised in the code. Is that possible? I should note...
Read more >
500 Internal Server Error - HTTP - MDN Web Docs - Mozilla
This error response is a generic "catch-all" response. Usually, this indicates the server cannot find a better 5xx error code to response.
Read more >
Should a REST API return a 500 Internal Server Error to ...
500 internal server means "It's our fault, we messed something up", and you should never aim to return this status to a user....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found