apollographql / apollo-server

🌍  Spec-compliant and production ready JavaScript GraphQL server that lets you develop in a schema-first way. Built for Express, Connect, Hapi, Koa, and more.
https://www.apollographql.com/docs/apollo-server/
MIT License
13.77k stars 2.03k forks source link

Throwing new error with custom error details inside try block does not get passed to the client #5673

Closed ghost closed 3 years ago

ghost commented 3 years ago

apollo-graphql@0.9.3 apollo-server-core@3.1.2

Code try { user = await User.findOne({ email: usernameOremail}); if (!user) { errors.general = "User not found"; throw new UserInputError("User-not-found", { errors }); } } }

Current behaviour { "errors": [ { "message": "UserInputError: User-not-found", "locations": [ { "line": 2, "column": 3 } ], "path": [ "login" ], "extensions": { "code": "INTERNAL_SERVER_ERROR", "exception": { "stacktrace": [ "Error: UserInputError: User-not-found", " at Object.login (/home/devil/Desktop/mern/Connect/graphql/resolvers/auth.resolver.js:76:15)", " at processTicksAndRejections (internal/process/task_queues.js:95:5)" ] } } } ], "data": null }

expected behaviour { "errors": [ { "message": "User-not-found", "locations": [ { "line": 2, "column": 3 } ], "path": [ "login" ], "extensions": { "errors": { "general": "User not found" }, "code": "BAD_USER_INPUT", "exception": { "stacktrace": [ "UserInputError: User-not-found", " at Object.login (/home/devil/Desktop/mern/Connect/graphql/resolvers/auth.resolver.js:44:19)", " at processTicksAndRejections (internal/process/task_queues.js:95:5)" ] } } } ], "data": null }

glasser commented 3 years ago

I understand what you expect and what you see, but this isn't enough detail for me to reproduce. For example, I don't see where errors is defined. I'd love to investigate this — I'll be happy to reopen if you provide a full reproduction. Something like codesandbox.io or instructions starting with git clone would help.

ghost commented 3 years ago

url url to codesandbox I have created a sandbox where I have provided the code and also commented out the details regarding that bug and also why that bug occurs

glasser commented 3 years ago

Hi @mdsadiqueinam . Your sandbox shows a very very old version of Apollo Server: 2.9.7, from October 2019. (I think this might be in a Codesandbox template? We just filed #5733 to better document how to use Codesandbox.)

The details of error handling custom properties actually got changed a bit in Apollo Server 3 so I don't think it makes sense for us to investigate issues related to this from Apollo Server 2. If you can still reproduce with AS3, let us know and we'll reopen!

ghost commented 3 years ago

I have upgraded the Apollo server to version 3.3.0 and I can still reproduce this bug, here is the link for Codesandbox, I request you to please read the comment in Codesandbox, there I have already written what the bug is and where it is occurring. Thank You

glasser commented 3 years ago

I had to make some changes to your repository to get it to run: we are not yet compatible with graphql 16 (https://github.com/apollographql/apollo-server/issues/5605) so I went back to graphql@15.6.0.

What you are showing is working as expected. Apollo Server's error handling looks for an extensions field on the error thrown by your resolver to find custom data like general as well as the code (which makes UserInputError BAD_USER_INPUT rather than INTERNAL_SERVER_ERROR).

When you call new Error(error), you're creating a new instance of the basic JS Error type, which doesn't have a concept of extensions at all. In fact, its first argument is just a string message, so everything about your error other than its message (and its typename: Error.toString() concatenates them together) is lost.

If you want your resolvers to throw errors with codes and other extensions, you should throw actual ApolloErrors (the class is in apollo-server-errors.