-
Notifications
You must be signed in to change notification settings - Fork 828
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
No longer able to catch unexpected errors after removal of UnforgivingExecutionContext #1368
Comments
This is my mistake, I apologize. Because the test cases relevant to the execution context failed (errors weren't swallowed), I assumed that we no longer needed it, because of graphql-core changes. We should definitely bring the execution context back. |
Thanks for the quick feedback @codebyaryan . I've created #1369 as a starting point on how we could handle that. |
Just to chime in here: the UnforgivingExecutionContext could contravene the spec: https://spec.graphql.org/June2018/#sec-Errors-and-Non-Nullability Thats not to say that there aren't reasons why you would want it (in tests for example) but it might break assumptions that a client makes if it was used in a server. The way we've approached this in Strawberry is to log all errors using the default logger by default and add a hook to allow you to customise error reporting: https://strawberry.rocks/docs/types/schema#handling-execution-errors We're also investigating adding a |
@jkimbo Here's our use case for what it's worth: Basically, there should never be anything within With both the original change and the proposed reimplementation, field resolvers can catch exceptions and explicitly reraise a At least in our schema, most fields are required so a cascading null can make the request pretty useless. Uncaught exceptions in web workers typically return a http 500 status code, which I'd expect a client to be able to handle about as well as a mostly empty response due to cascading nulls. Reraising the original exception allows us to reuse other error handling/reporting code already present for non-graphql requests, and also makes it easy to track/alert on error rates (based on http status codes) across the application. |
@AlecRosenbaum thats makes a lot of sense. I think there might be a way to solve your use case withougt having to implement a custom execution context though. In Strawberry this would be done by implementing an extension (example code here: strawberry-graphql/strawberry#1221 (comment)) but since Graphene doesn't have an equivalent you would have to override the import logging
import graphene
from graphql import GraphQLError
from graphql.error import format_error
logger = logging.getLogger("graphene.execution")
class VisibleError(Exception):
# Raise this if you want the error message to be returned in the response
pass
class CustomSchema(Schema):
def execute(self, *args, **kwargs):
result = super().execute(*args, **kwargs)
if result.errors:
processed_errors = []
for error in result.errors:
logger.error(error, exc_info=error.original_error, stack_info=True)
# Explicitly log to Sentry/Rollbar here if needed
if error.original_error and not isinstance(error.original_error, (VisibleError, GraphQLError)):
processed_errors.append(
GraphQLError(
message="Unexpected error.",
nodes=error.nodes,
source=error.source,
positions=error.positions,
path=error.path,
original_error=None
)
)
else:
processed_errors.append(error)
result.errors = processed_errors
return result See it in action here: https://replit.com/@jkimbo/ShadowyInexperiencedSeptagon#main.py Admittedly this doesn't solve the issue around returning a 500 HTTP status code but that could be solved by checking if there are errors and no data in the view and changing the status code there. Or actually raising in the above |
Since the introduction of Add UnforgivingExecutionContext #1255 by @AlecRosenbaum it was possible to raise unexpected errors to the backend processing, as examplained in Error handling #902 (comment). This is critical so you get a decent traceback in the log and no error message for each record in the result set, ie
Changes in graphql-core started to let the UnforgivingExecutionContext tests fail, as recorded by @mweinelt in #1346 and noted by @weilu #1255 (comment) with a suggestion for a potential fix.
#1357 by @codebyaryan brought in welcome changes for query validation, but also removed UnforgivingExecutionContext in #1357 (comment)
a github repo, https://repl.it or similar.
If we bring back the Test case for UnforgivingExecutionContext without specifying UnforgivingExecutionContext per this configuration alexhafner@0aaa3fc, we get those tests failing because unexpected errors are no longer being raised up: https://gist.github.com/alexhafner/5215ef726b356eef6571efb969f6a3e7
Be able to stop processing a graphql operation when an unexpected error occurs, return a top-level error message to the GraphQL user, and get a full stack trace in the backend to be able to act on the error message further.
For example:
If we bring back UnforgivingExecutionContext, and create a similar solution to the one in #1255 (comment), the tests succeed again as shown here: https://gist.github.com/alexhafner/a78f493f1b869df0ba112b4acb5da5e9. The approach in alexhafner@f765537 raises the original errors for non-GraphQL Errors, and handles GraphQL Errors unchanged by using super() on handle_field_error().
other solutions are welcome
catching unexpected issues is system and security critical, and a full stack trace is needed.
Please tell us about your environment:
Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow)
N/A
The text was updated successfully, but these errors were encountered: