New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added rawOriginalError to GraphQLError. This will allow errors to sur… #3379
Conversation
…face to the logger that do not inherit Error.
|
@burtontanner Throwing non-errors are widely considered a bad practice in JS. |
First off thanks for the quick response! The error is being thrown from a node_module. I don't think I can get it changed anytime soon. But also, if any other node_module throws something that does not inherit from Error, then we may or may not see the details of the error. Unfortunately the chances of another module throwing errors in this way is high in my opinion. |
@burtontanner Bad practices in I will try to figure out how to solve you problem with minimal impact. |
For another opinion… In TS, errors caught by catch were typed as any or now unknown, right, which is correct, not typed as Error? It doesn’t seem wrong to relax the type of originalError to match the actual type in the language we can suggest best practices, but seems a bit strange to not accommodate valid, worse practices in graphql js if they are allowed by the language. i might be missing something. Though we also should think about in this context the duck typing of errors with a path attribute as valid located errors, is that a problem if these errors are not actual Error instances. do we need other code changes, tests to ensure no problem. (Separate issue, do we even want to keep that duck typing?) |
@yaacovCR It both breaking change and also result in worse DX. Bad practices should be contained and in general if "you don't use bad practices you shouldn't pay for someone who uses them with worse DX".
It's a legacy thing, now that we require single |
Thank you for this change! @IvanGoncharov |
I agree with you that what I am suggesting is a breaking change and therefore has to wait until v17. But I think it is the right way to go.... What you suggest in the linked PR does preserve the thrownValue, which functionally is all the original poster @burtontanner needs, but in my opinion, is not the right path forward.
Just some thoughts. Not a huge deal. |
@yaacovCR It makes worse DX for downstream libs and end-devs since you need to do
TC39 can't change the language so they support throwing non-Erors which is not universally supported (e.g. Python doesn't that). Same with TS it documents what can happen in runtime.
But to be fair it looks like Angular type errors as So it proves that some of the most popular libraries can force their own conventions on top of JS and the whole ecosystem moves in the direction of "errors being errors". |
Lol, it may be that throwing a non Error is a bad practice, but it’s quite strong to say that it’s an error, and it’s certainly not an Error. The proof is #3384 itself, which makes it so, even though it wasn’t previously. i do agree with you that by wrapping we provide the inspected value for free, which may be helpful, but since we already wrap the original error as a GraphQLError we can provide that value within the message of the wrapping GraphQLError and correctly preserve the original error as the original error. The only benefit of the extra level of wrapping that I see is that we convert a bad practice into an Error and the real world value of that is dubious. in terms of the links you have cited, they do not show how those types are correct, ie where react converts non Error errors into Errors or how, and I don’t believe there is a convention on that, and I don’t believe graphql JS should get ahead of the community on that. Finally, even if we have gone this route temporarily, in v17 we have to make a change now to the name of originalError, which is now not quite so original. To call throwing a non error an error is one thing, but to call it the original error is really quite wrong |
This seemingly is what vue does: meaning, they do nothing, they just type errors as Errors in their typings? because our code is in typescript (and previously flow) our code is typed and therefore we don’t/can’t make that error at least |
Further investigation reveals that this "non-Error error => Error" conversion was introduced here graphql-js/src/execution/execute.js Lines 539 to 542 in f62c0a2
The "consistent Error interface" that @leebyron presumably is talking about has to do with error handling within the completeValue function, not within handlers analyzing the originalError, because this was before the originalError was retained. Now that the code has been so well refactored, we can dispense with this double wrapping. |
Aded rawOriginalError to GraphQLError. This will allow errors to surface to the logger that do not inherit Error.