Graphql-js: GraphQL Stack Traces are (Needlessly) Unhelpful;

Created on 9 Oct 2019  路  5Comments  路  Source: graphql/graphql-js

Here is a stack trace I recently got:

 Error: Cannot return null for non-nullable field User.id.
    at completeValue (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:560:13)
    at completeValueCatchingError (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:495:19)
    at resolveField (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:435:10)
    at executeFields (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:275:18)
    at collectAndExecuteSubfields (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:713:10)
    at completeObjectValue (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:703:10)
    at completeValue (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:591:12)
    at completeValueCatchingError (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:495:19)
    at resolveField (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:435:10)
    at executeFields (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:275:18)
    at collectAndExecuteSubfields (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:713:10)
    at completeObjectValue (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:703:10)
    at completeValue (/home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:591:12)
    at /home/me/projects/my-project/server/node_modules/graphql/execution/execute.js:492:16

The problem is, it's entirely made up of lines from graphql, which means it's entirely worthless for helping me understand where the error occurred (ie. the entire thing stack traces are _supposed_ to do). All I know is that it involved a resolver which somehow involved a User ID.

I don't mean to sound ungrateful for awesome free software (that is the best way to build an API today) ... and I _very much am_ appreciative of all the hard work that has gone into this project ... but would it kill you to at least include the query and variables used in the stack trace?

At the moment it really feels like the library is saying "Oh you messed up? Well, too bad: you're on your own now chump! That's you what you get for making a mistake." ;) But surely you _want_ to help users understand errors, no? And surely GraphQL has the query/variables available to include in the error, since it receives both long before the error occurs?

enhancement

Most helpful comment

@machineghost Thanks for your report 馃憤
It's definitely something we should try to address since I fully agree that current error gives you an absolute minimum of info.
By default JS environments output description + call trace and we can't include a query or query variables into description since they can be huge and description is sent to the API client.
However, I definitely agree that we should try to find solutions to provide more details in printed error messages.

At the moment we are in feature freeze due to the upcoming TS conversion but after it's done we will definitely try to address this problem.

All 5 comments

@machineghost Thanks for your report 馃憤
It's definitely something we should try to address since I fully agree that current error gives you an absolute minimum of info.
By default JS environments output description + call trace and we can't include a query or query variables into description since they can be huge and description is sent to the API client.
However, I definitely agree that we should try to find solutions to provide more details in printed error messages.

At the moment we are in feature freeze due to the upcoming TS conversion but after it's done we will definitely try to address this problem.

Awesome. Specifically, regarding:

By default JS environments output description + call trace and we can't include a query or query variables into description since they can be huge and description is sent to the API client.

Fair enough, but even _just_ the first 100 characters of the query (_maybe_ coupled with as many keys of the variables object as would fit?) would likely be enough to narrow down the source of the error in 95+% cases.

@machineghost We already have custom toString() that output description + locations on all errors so you can do:

console.log(error.toString() + '\n\n' + error.stack)
Cannot return null for non-nullable field Query.id.

GraphQL request:3:5
2 |   {
3 |     id
  |     ^
4 |   }

Error: Cannot return null for non-nullable field Query.id.
    at completeValue (/dist/execution/execute.js:574:13)
    at completeValueCatchingError (/dist/execution/execute.js:509:19)

But then you have to catch and log the error (specifically as a string) to see that info.

Surely you would agree that, just in general, it would be more convenient if a developer can 1) get an error, 2) immediately determine where it came from, without additional effort required?

And more importantly, wouldn't you also agree that if the _entire problem_ is that you can't tell where the error came from in the first place, being able to get more info when you log it (AFTER you find it) isn't very helpful?

@machineghost I definitely agree with all your points just wanted to specify that it's possible to do using the above workaround.

Was this page helpful?
0 / 5 - 0 ratings