-
Notifications
You must be signed in to change notification settings - Fork 2k
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
GraphQL Error Swallowed Natively but works in Express-graphql #1326
Comments
@alifaff You shouldn't wrap
Not sure that I fully understand your question. Can you please provide a minimal example of the actual and expected output. |
Sorry...the params was meant as a place holder for loaders and other context items (should have used different terminology). See below a sample mutation:
The function createClient generates a custom error as below:
We would like the output to be as follows:
The above works fine with express-graphql however using it through Lambda and natively calling graphql graphql(schema, query, null, {contextParams}, variables) does not seem to return an error rather only get back the following:
The setup is the same for both using the same schema, however the only difference is that it does not contain the formatError. Below is the code when using express-graphql:
Let me know if you need anything else. Thanks |
My colleague has created a Github project located here: https://github.com/marc-at/exception-graphql To run locally: npm run dev |
@alifaff Nothing prevents you from writing: const runGraphQL = (query, variables, params) => {
const result = graphql(schema, query, null, {params}, variables);
if (result.errors) {
result.errors = result.errors.map(graphqlErrorManager.manageGraphErrors);
}
} Which is exactly what However, it's bad practice since GraphQL errors should follow the certain structure:
You can add additional properties only inside The ideal solution would be to do this: class ApiError extends Error {
constructor(type, ...errors) {
super(...errors)
if (Error.captureStackTrace) {
Error.captureStackTrace(this, ApiError)
}
this.extensions = {
date: new Date(),
type,
errors
};
}
} GraphQL library recognise |
Thank you for the quick feedback. We have updated the code in Github to reflect the change to ApiError. Unfortunately, that still does not return the error back properly. We still get back empty errors:
Will you please take a quick look at the simple example project we have created to https://github.com/marc-at/exception-graphql To run locally: npm run dev |
@alifaff Works for me: |
@alifaff Or should I call it differently? if (result && result.errors) {
result.errors = result.errors.map(formatError);
} Before returning result. |
Hi Ivan! That is correct that I have to stringify or return a string when throwing a GraphQLError for it to come through, however we used to use version 0.11.2 and that would return back the object. Yes it works with express-graphql but not using AWS Lambda. I believe something has changed in version 13.2 with GraphQLError that does not allow us to wrap the custom error with GraphQLError when running it in Lambda/node server. Could this some sort of bug on this version? I am going to try all of the different version between 0.11.2 and 0.13.2 and see which version began returning an empty set. I will return back with the version shortly. Thanks |
Quickly ran different versions and found the last version 0.11.7 worked fine, however in version 0.12.0, it returns empty. |
@alifaff Could you please run this code on const result = execute(...);
console.log(JSON.stringify(result.errors[0])) And post results here. |
@alifaff Also please copy the result of |
v0.12.0:seems to select 0.12.3 v0.11.7: |
@alifaff You shouldn't wrap it with GraphQLError just
Why are you doing that:
This library works as expected. You shouldn't just randomly pass arguments to function/constructors please read documentation first. |
@IvanGoncharov The constructor does have string as the first argument, in our case 'type' is string. The usage with new ApiError('Input' where 'Input' is a string. I understand that it will work with new Error(somestring), however we want to return a custom error with the type of error, root cause of the error, message to be returned to the client, and message to display to the end user. Since we want to customize the error we built our custom Error which does follow the guideline when Error needs to be extended. I guess another way to solve the problem is to ask how do we send custom error messages back that are not only string specific but has some allowable structure to it? |
I suspect a problem with serverless and possibly apollo-client and graphql versions where the graphql version differ and for one reason or another it drops everything but the message in errors. ├── graphql@0.12.3 |
@alifaff I'm talking about standard |
Thanks...I have tried everything you have provided however nothing seems to be working. As mentioned it was working up until version 11.7 and something changed in version 12.0. Anything that might ring a bell in terms of difference between the two versions that could have potentially altered the output. Problem is related to throwing an error with an object as opposed to a string which works just fine and seems to be caused when using graphql natively or in a node server. |
@alifaff From the result of: const result = execute(...);
console.log(JSON.stringify(result.errors[0])) I see that library works as expected. That mean problems are in your code. So the only way I can help you if you create sample code that I can run locally. |
@IvanGoncharov Tried to see if we can run it through serverless locally and it works, however when we run it through AWS Lambda the errors are empty. I am not sure how we can get you test it locally without actually running it in Lambda. For the time being I will close the ticket, but we will see what change is making Lambda break. Thank you for all of your help, we really appreciate it! |
It turns out the reason we were seeing different results when executing on lambda was the way we were building the response.
JSON.stringify(body) attempts to stringify the Error and, by design, it doesn't include all the extra properties. A few solutions are discussed on SO. |
@marc-at Entire GraphQL response should be serializable can you please post here a sample code similar to this: const schema = ...
const query = ...
execute(schema, query)
.then(result => console.log(JSON.stringify(result)); And its actual and expect results. If you speaking of missing if (result && result.errors) {
result.errors = result.errors.map(formatError);
} |
Thanks. That worked. |
Thank you very much @IvanGoncharov for helping us walk through this problem. Really appreciate all of your support! |
Using Graphql 0.13.2
Executing graphql natively as follows through AWS Lambda:
index.js - calls
If the executing code throws an error, it usually returns message as string with [object, Object]. I suspect it wraps to GraphQLError. If I wrap the above error object using GraphQLError then I do not get anything back and my response.errors is an empty object {}. The only way I am able to get back data properly is to return an Error as a string or a GraphQLError as a string, I am unable to push back an object.
Oddly enough if I run GraphQL with express and add the formatError with an error handler then that works, however using it natively it does not.
It seems that I am missing something simple to get GraphQL to return the object instead of only working with strings. Any ideas?
The text was updated successfully, but these errors were encountered: