-
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
AWS Lambda version on node 8.10 returns statusCode 400 on graphql error #1004
Comments
Are you saying that the query sent from the client was syntactically incorrect/malformed? Can you give an example of the query? Keeping in mind that the logic behind the choosing HTTP status codes (outside of the context of GraphQL) is not isolated to the transport layer, are you suggesting that you would expect a 200 status code in the event of a syntax error encountered while parsing the query? |
Hi @abernix, I think there are generally 2 cases:
|
@dacz I'd expect the body to be passed on by API GW, is this not the case? If so, and the client feels lucky enough to not check the HTTP status of her request she would still be able to inspect the "errors" in the body, like she would for 200s. |
@ojongerius I'm not looking for workaround, as I stated in the point 2. of my previous comment, I believe that GraphQL server (understand apollo graphql lambda) should return 200 and well-formed GraphQL request (with errors). I believe that apollo lambda does this correctly on node 6.10, but AWS now supports node 8.10 with async and this is the case where the return status code is not correct. The reason I posted it here is to know if this is desired behaviour of apollo lambda with node 8.10 or not and if not, flag it as a bug and community or apollo may fix it. |
@dacz IMO, you should use Instead of importing additional ~228.3KB P.S. authors should split the exporting of the modules into separate files, so that we could properly import exactly what we need. |
Just hit this issue. I agree that it would be nice if it was consistent. I don't think its a node version issue. Below is the code block, I think is responsible, for returning the 400 vs 200 response code. It's seems to be because validation errors don't have data set by default. Also, I think this returns before the custom resolver you provide gets called, so you cannot even override the response code. The other issue with it getting called without the resolver is that, say you are missing one field "name", but have other fields that are present, that would throw errors (maybe "age" < 18). You will only get the missing field error back with the first request, so you will have to call the api a second time to get the age error. This is all a bit new to me, but if the best practice for graphql is that errors should be returned with 200. I feel that "required" validation errors should fall into the same category as any other custom validation errors and return the same response code. Maybe setting data to null would be a solution. That said maybe there is a good reason for the 400 code. CurrentBeta 7if (!isBatch) {
const gqlResponse = responses[0];
//This code is run on parse/validation errors and any other error that
//doesn't reach GraphQL execution
if (gqlResponse.errors && typeof gqlResponse.data === 'undefined') {
throw new HttpQueryError(400, prettyJSONStringify(gqlResponse), true, {
'Content-Type': 'application/json',
});
}
return prettyJSONStringify(gqlResponse);
} Master if (!isBatch) {
const gqlResponse = responses[0];
if (gqlResponse.errors && typeof gqlResponse.data === 'undefined') {
throw new HttpQueryError(400, JSON.stringify(gqlResponse), true, {
'Content-Type': 'application/json',
});
}
return JSON.stringify(gqlResponse);
} Maybe a solutionif (!isBatch) {
const gqlResponse = responses[0];
//This code is run on parse/validation errors and any other error that
//doesn't reach GraphQL execution
if (gqlResponse.errors && typeof gqlResponse.data === 'undefined') {
// set data to null and return 200 just like other errors
gqlResponse.data = null
throw new HttpQueryError(200, prettyJSONStringify(gqlResponse), true, {
'Content-Type': 'application/json',
});
}
return prettyJSONStringify(gqlResponse);
} Happy to create a pull request for this if someone with merge rights is happy to accept the request. |
Thanks for logging this originally. I'm going to close this issue since It hasn't received much traction in quite some time and I'm fairly sure that we have a good number of users utilizing Apollo Server on Lambda. We've also changed substantial portions of Apollo Server since then and accepted a lot of PRs which change the If this is still a problem, feel free to ping me back and I (or someone) will be happy to re-open it, though please do be prepared to provide a run-able reproduction so we can get to the bottom of the issue quickly. (Also for Lambda, this would be even better if this reproduction was also a |
@abernix this is one of those super annoying gotchas which drives me nuts ... we have to dig into hidden parts of the apollo server repo to find the status code for errors, which makes it super hard to set up CORS properly in api gateway. just blew hours on this issue, please reopen and simply document the status codes, as they are critical for CORS configuration |
@bionicles I agree with @o-alexandrov fully. When you need better control, it's better not to use Apollo server but use graphql package directly. In Apollo server there is not only graphiql but the scaffolding to connect to their commercial services, too. 4 months ago I did reference implementtion and found:
One thing that you should be aware of is that Apollo server caches the parsed queries in memory (with some LRU cache package as I remember). It's easy to implement it. And for serverless environment (aws lambda) you can go even way further - use elasticache (redis) as this cache and you get shared parsed query cache across multiple lambdas. The "only" gotcha is cache invalidation, but when you go down the way to have this infrastructure (and you need heavy duty graphql server as lambda), it's not so hard to do so and you can fine tune your cache for your requirements (based on queries etc., frequency, etc). The beautifiul benefit is that you get the solution that you can tweak the way you want. I had CORS problems, too and I had to make some weird workarounds to add my own header with request id for debugging. |
GraphQL Lambda
Invalid graphql query returns correct graphql response with errors but the statusCode is 400 instead of 200.
My lambda is simple enough (90% is the example from docs with
callbackFilter
).I modified the
callbackFilter
as follows to sort out the error:The statusCode was returned even the error was undefined.
Desired outcome
Return statusCode 200 by default.
The text was updated successfully, but these errors were encountered: