question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow to configure exception catching for schema execution

See original GitHub issue

Currently, any exception that is raised in a resolver is catched and converted to a GraphQLError, which is returned in the errors part of the result (see strawberry/schema/execute.py).

However, this is not always desirable. For example, the error message might contain sensitive information about the server that should not be accessible to a client. Instead, the server should return a 500 HTTP error (which would work more or less automatically if the exception is not catched). So we need a possibility to tell strawberry that it should not catch all exceptions, but only specific ones. This could mean catching only GraphQLError, or allowing the user to define a set of exceptions that should be catched.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:3
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

5reactions
jkimbocommented, Sep 11, 2021

@N-Maas I think there are 2 issues that you have outlined here and they are slightly different:

1. Error messages might contain sensitive information about the server

This is true and we’d like to make it easier to hide error messages using extensions (see https://github.com/strawberry-graphql/strawberry/issues/1155). Until then here is a custom extension that only allows certain errors to be included in the response:

from graphql import GraphQLError
from strawberry.extensions import Extension

class VisibleError(Exception):
	pass

class MaskErrors(Extension):
	def on_request_end(self):
		result = self.execution_context.result
		if result.errors:
			processed_errors = []
			for error in result.errors:
				
				if error.original_error and not isinstance(error.original_error, VisibleError):
					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

@strawberry.type
class Query:
	@strawberry.field
	def my_field(self) -> str:
		raise VisibleError("This error message is visible to the client")

	@strawberry.field
	def my_second_field(self) -> str:
		raise Exception("This error message is renamed to 'Unexpected error.'")

schema = strawberry.Schema(Query, extensions=[MaskErrors])

(I’ll make a PR for this soon so that you can use it directly from strawberry)

2. The server should return a 500 if there are any/some errors

The GraphQL spec actually defines how a server should deal with errors and it explicitly says that errors should be caught and added to the “errors” response: https://spec.graphql.org/June2018/#sec-Errors-and-Non-Nullability There is also a draft spec for “GraphQL over HTTP” which defines the status codes that the server should return: https://github.com/graphql/graphql-over-http/blob/main/spec/GraphQLOverHTTP.md#status-codes

So it’s unlikely that Strawberry will support returning 500 errors if there is an error or selectively catching specific exceptions since it contravenes the spec.


I hope thats helpful and that I characterised your question correctly. Let me know if I’ve missed anything.

0reactions
blueyedcommented, Jul 25, 2022

@jkimbo indeed. In the case at hand it comes via:

  [33] …/project/app/api/test_bar.py(90)test_baz()
       result = schema.execute_sync(query, variable_values={"urn": foo.urn})
  [34] …/project/.venv/lib/python3.10/site-packages/strawberry/schema/schema.py(231)execute_sync()
       result = execute_sync(
  [35] …/project/.venv/lib/python3.10/site-packages/strawberry/schema/execute.py(193)execute_sync()
       result = original_execute(
  [36] …/project/.venv/lib/python3.10/site-packages/graphql/execution/execute.py(1030)execute()
       result = exe_context.execute_operation(operation, root_value)
  [37] …/project/.venv/lib/python3.10/site-packages/graphql/execution/execute.py(353)execute_operation()
       return (
  [38] …/project/.venv/lib/python3.10/site-packages/graphql/execution/execute.py(431)execute_fields()
       result = self.execute_field(
  [39] …/project/.venv/lib/python3.10/site-packages/graphql/execution/execute.py(557)execute_field()
       error = located_error(raw_error, field_nodes, path.as_list())
  [40] …/project/.venv/lib/python3.10/site-packages/graphql/error/located_error.py(50)located_error()
       return GraphQLError(message, nodes, source, positions, path, original_error)
> [41] …/project/.venv/lib/python3.10/site-packages/graphql/error/graphql_error.py(132)__init__()
       self.original_error = original_error

I’ve come up with the following to raise any original errors, which works good for tests, but could also make sense in general then:

class Schema(StrawberrySchema):
    def process_errors(
        self,
        errors: "list[GraphQLError]",
        execution_context: "ExecutionContext" = None,
    ) -> None:
        super().process_errors(errors, execution_context)

        for error in errors:
            err = getattr(error, "original_error")
            if err:
                raise err
Read more comments on GitHub >

github_iconTop Results From Across the Web

Error handling - Apollo GraphQL Docs
A client sent the hash of a query string to execute via automatic persisted queries, but the server has disabled APQ. OPERATION_RESOLUTION_FAILURE. The...
Read more >
JDBC Exception Handling - How To Handle SQL Exceptions
This JDBC Exception Handling tutorial explains ways to handle SQL Exceptions with the help of programming examples.
Read more >
Spring Boot GraphQL Tutorial #8 - Exception Handling with ...
Spring boot graphql supports Spring web's @ExceptionHandler annotations. To enable this we first need to set the graphql property: ...
Read more >
7 Handling PL/SQL Errors
To handle raised exceptions, you write separate routines called exception handlers. After an exception handler runs, the current block stops executing and the ......
Read more >
Handle errors in ASP.NET Core | Microsoft Learn
Startup exception handling ... Only the hosting layer can handle exceptions that take place during app startup. The host can be configured to ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found