def format_error(error): if isinstance(error, GraphQLLocatedError): error = error.original_error formatted_error = format_graphql_error(error) graphql_error = OrderedDict([('type', error.__class__.__name__)]) graphql_error['extensions'] = {} graphql_error['message'] = formatted_error['message'] if isinstance(error, exceptions.GraphQLError): if error.extensions: graphql_error['extensions'] = error.extensions graphql_error['extensions']['code'] = error.code else: graphql_error['extensions']['code'] = 'ERROR' if 'location' in formatted_error: graphql_error['location'] = formatted_error['location'] if error.__traceback__ is not None: info = error.__traceback__.tb_frame.f_locals.get('info') if info is not None: graphql_error['path'] = [info.field_name] graphql_error['operation'] = info.operation.operation if settings.DEBUG: graphql_error['extensions'][ 'stacktraceback'] = traceback.format_list( traceback.extract_tb(error.__traceback__)) return graphql_error
def format_error(error): if isinstance(error, GraphQLError): result = format_graphql_error(error) else: result = {"message": str(error)} exc = error while isinstance(exc, GraphQLError) and hasattr(exc, "original_error"): exc = exc.original_error logger.error("Exception information:", exc_info=exc) if settings.DEBUG: lines = [] if isinstance(exc, BaseException): for line in traceback.format_exception( type(exc), exc, exc.__traceback__ ): lines.extend(line.rstrip().splitlines()) result["extensions"] = { "exception": {"code": type(exc).__name__, "stacktrace ": lines} } return result
def format_error(cls, error): if isinstance(error, GraphQLError): result = format_graphql_error(error) else: result = {"message": str(error)} exc = error while isinstance(exc, GraphQLError) and hasattr(exc, "original_error"): exc = exc.original_error if isinstance(exc, cls.HANDLED_EXCEPTIONS): handled_errors_logger.error("A query had an error", exc_info=exc) else: unhandled_errors_logger.error("A query failed unexpectedly", exc_info=exc) result["extensions"] = {"exception": {"code": type(exc).__name__}} if settings.DEBUG: lines = [] if isinstance(exc, BaseException): for line in traceback.format_exception(type(exc), exc, exc.__traceback__): lines.extend(line.rstrip().splitlines()) result["extensions"]["exception"]["stacktrace"] = lines return result
async def handle_graphql(self, request: Request) -> Response: if request.method in ("GET", "HEAD"): if "text/html" in request.headers.get("Accept", ""): if not self.graphiql: return PlainTextResponse( "Not Found", status_code=status.HTTP_404_NOT_FOUND) return await self.handle_graphiql(request) data = request.query_params # type: typing.Mapping[str, typing.Any] elif request.method == "POST": content_type = request.headers.get("Content-Type", "") if "application/json" in content_type: data = await request.json() elif "application/graphql" in content_type: body = await request.body() text = body.decode() data = {"query": text} elif "query" in request.query_params: data = request.query_params else: return PlainTextResponse( "Unsupported Media Type", status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE, ) else: return PlainTextResponse( "Method Not Allowed", status_code=status.HTTP_405_METHOD_NOT_ALLOWED) try: query = data["query"] variables = data.get("variables") operation_name = data.get("operationName") except KeyError: return PlainTextResponse( "No GraphQL query found in the request", status_code=status.HTTP_400_BAD_REQUEST, ) background = BackgroundTasks() context = {"request": request, "background": background} result = await self.execute(query, variables=variables, context=context, operation_name=operation_name) error_data = ([format_graphql_error(err) for err in result.errors] if result.errors else None) response_data = {"data": result.data} if error_data: response_data["errors"] = error_data status_code = (status.HTTP_400_BAD_REQUEST if result.errors else status.HTTP_200_OK) return JSONResponse(response_data, status_code=status_code, background=background)
def format_error(error): if hasattr(error, 'original_error'): err = error.original_error formatted_error = {} if isinstance(err, AppException): if isinstance(err, InternalErrorException): log_error(err.detail, exc_info=(err.__class__, err, err.stack)) formatted_error['message'] = err.detail formatted_error['code'] = err.code else: log_error('Exception during GraphQL method execution.', exc_info=(err.__class__, err, err.stack)) formatted_error['message'] = 'Internal error.' formatted_error['code'] = InternalErrorException.code if hasattr(err, 'errors') and err.errors is not None: formatted_error['errors'] = [{ 'key': to_camel_case(x.key), 'message': x.message } for x in err.errors] if error.locations is not None: formatted_error['locations'] = [{ 'line': loc.line, 'column': loc.column } for loc in error.locations] return formatted_error if isinstance(error, GraphQLError): return format_graphql_error(error) return {'message': str(error)}
def process_result(result: ExecutionResult) -> GraphQLHTTPResponse: data: GraphQLHTTPResponse = {"data": result.data} if result.errors: data["errors"] = [format_graphql_error(err) for err in result.errors] return data
def format_error(error): try: if isinstance(error, GraphQLLocatedError): return format_located_error(error) if isinstance(error, GraphQLSyntaxError): return format_graphql_error(error) except Exception as e: return format_internal_error(e)
def format_error(error): if isinstance(error, GraphQLError): return format_graphql_error(error) return { 'message': '{}: {}'.format(error.__class__.__name__, six.text_type(error)) }
def format_error(error): # Why don't other people care about stack traces? It's absurd to have add this myself trace = traceback.format_exception(etype=type(error), value=error, tb=error.__traceback__) if isinstance(error, GraphQLError): return R.merge(dict(trace=trace), format_graphql_error(error)) return {"message": six.text_type(error), "trace": trace}
async def handle_subscribe(self, message: SubscribeMessage) -> None: if not self.connection_acknowledged: await self.close(code=4401, reason="Unauthorized") return if message.id in self.subscriptions.keys(): reason = f"Subscriber for {message.id} already exists" await self.close(code=4409, reason=reason) return context = await self.get_context() root_value = await self.get_root_value() if self.debug: # pragma: no cover pretty_print_graphql_operation( message.payload.operationName, message.payload.query, message.payload.variables, ) try: result_source = await self.schema.subscribe( query=message.payload.query, variable_values=message.payload.variables, operation_name=message.payload.operationName, context_value=context, root_value=root_value, ) except GraphQLError as error: payload = [format_graphql_error(error)] await self.send_message( ErrorMessage(id=message.id, payload=payload)) self.schema.process_errors([error]) return if isinstance(result_source, GraphQLExecutionResult): assert result_source.errors payload = [format_graphql_error(result_source.errors[0])] await self.send_message( ErrorMessage(id=message.id, payload=payload)) self.schema.process_errors(result_source.errors) return handler = self.handle_async_results(result_source, message.id) self.subscriptions[message.id] = result_source self.tasks[message.id] = asyncio.create_task(handler)
def error_format(exception): if isinstance(exception, ExecutionError): return [{"message": e} for e in exception.errors] elif isinstance(exception, GraphQLError): return [format_graphql_error(exception)] elif isinstance(exception, web.HTTPError): return [{"message": exception.log_message, "reason": exception.reason}] else: return [{"message": "Unknown server error"}]
def error_format(exception): if isinstance(exception, ExecutionError): return [{'message': e} for e in exception.errors] elif isinstance(exception, GraphQLError): return [format_graphql_error(exception)] elif isinstance(exception, web.HTTPError): return [{'message': exception.log_message}] else: return [{'message': 'Unknown server error'}]
async def handle_graphql(self, request: Request) -> Response: if request.method == "GET": if "text/html" in request.headers.get("Accept", ""): return await self.handle_graphiql(request) data = request.query_params # type: typing.Mapping[str, typing.Any] elif request.method == "POST": content_type = request.headers.get("Content-Type", "") if "application/json" in content_type: data = await request.json() elif "application/graphql" in content_type: body = await request.body() text = body.decode() data = {"query": text} elif "query" in request.query_params: data = request.query_params elif "multipart/form-data" in content_type: form = await request.form() data = {} file_map = json.loads(form["file_map"]) data = {"query": form["query"]} variables = json.loads(form["variables"]) for key, path in file_map.items(): variables[path] = await form[key].read() data["variables"] = variables else: return PlainTextResponse( "Unsupported Media Type", status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE, ) else: return PlainTextResponse( "Method Not Allowed", status_code=status.HTTP_405_METHOD_NOT_ALLOWED) try: query = data["query"] variables = data.get("variables") operation_name = data.get("operationName") except KeyError: return PlainTextResponse( "No GraphQL query found in the request", status_code=status.HTTP_400_BAD_REQUEST, ) result = await self.execute(query, variables) error_data = ([format_graphql_error(err) for err in result.errors] if result.errors else None) response_data = {"data": result.data, "errors": error_data} status_code = (status.HTTP_400_BAD_REQUEST if result.errors else status.HTTP_200_OK) return JSONResponse(response_data, status_code=status_code)
async def start_subscription(self, data, operation_id: str, websocket: WebSocket): query = data["query"] variables = data.get("variables") operation_name = data.get("operation_name") if self.debug: pretty_print_graphql_operation(operation_name, query, variables) data = await subscribe(self.schema, query, variable_values=variables, operation_name=operation_name) try: async for result in data: payload = {"data": result.data} if result.errors: payload["errors"] = [ format_graphql_error(err) for err in result.errors ] await self._send_message(websocket, GQL_DATA, payload, operation_id) except Exception as error: if not isinstance(error, GraphQLError): error = GraphQLError(str(error), original_error=error) await self._send_message( websocket, GQL_DATA, { "data": None, "errors": [format_graphql_error(error)] }, operation_id, ) await self._send_message(websocket, GQL_COMPLETE, None, operation_id) if self._keep_alive_task: self._keep_alive_task.cancel() await websocket.close()
def error_format(exception): if isinstance(exception, ExecutionError): return [{'message': e} for e in exception.errors] elif isinstance(exception, GraphQLError): return [format_graphql_error(exception)] elif isinstance(exception, web.HTTPError): return [{'message': exception.log_message, 'reason': exception.reason}] else: return [{'message': 'Unknown server error'}]
async def handle_async_results(self, results: typing.AsyncGenerator, operation_id: str, websocket: WebSocket): try: async for result in results: payload = {"data": result.data} if result.errors: payload["errors"] = [ format_graphql_error(err) for err in result.errors ] await self._send_message(websocket, GQL_DATA, payload, operation_id) except asyncio.CancelledError: # CancelError will be received when the client disconnects # and the `handle_async_results` task gets cancelled # Suppress the error and prevent sending any message, since the # client was disconnected now return except Exception as error: if not isinstance(error, GraphQLError): error = GraphQLError(str(error), original_error=error) await self._send_message( websocket, GQL_DATA, { "data": None, "errors": [format_graphql_error(error)] }, operation_id, ) if (websocket.client_state != WebSocketState.DISCONNECTED and websocket.application_state != WebSocketState.DISCONNECTED): try: await self._send_message(websocket, GQL_COMPLETE, None, operation_id) except ConnectionClosedError: pass
async def get_http_response( request: Request, execute: typing.Callable, graphiql: bool ) -> Response: if request.method == "GET": if not graphiql: return HTMLResponse(status_code=status.HTTP_404_NOT_FOUND) html = get_graphiql_html() return HTMLResponse(html) if request.method == "POST": content_type = request.headers.get("Content-Type", "") if "application/json" in content_type: data = await request.json() else: return PlainTextResponse( "Unsupported Media Type", status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE, ) else: return PlainTextResponse( "Method Not Allowed", status_code=status.HTTP_405_METHOD_NOT_ALLOWED, ) try: query = data["query"] variables = data.get("variables") operation_name = data.get("operationName") except KeyError: return PlainTextResponse( "No GraphQL query found in the request", status_code=status.HTTP_400_BAD_REQUEST, ) context = {"request": request} result = await execute( query, variables=variables, context=context, operation_name=operation_name, ) response_data = {"data": result.data} if result.errors: response_data["errors"] = [ format_graphql_error(err) for err in result.errors ] return JSONResponse(response_data, status_code=status.HTTP_200_OK)
def execute_graphql_subscription( self, websocket: WebSocket, operation_id: str, query: str, variables: Optional[Dict[str, Any]], operation_name: Optional[str], ) -> Tuple[Optional[Task], Optional[Dict[str, Any]]]: request_context = self.make_request_context(websocket) try: async_result = self._graphql_schema.execute( query, variables=variables, operation_name=operation_name, context=request_context, allow_subscriptions=True, ) except GraphQLError as error: error_payload = format_graphql_error(error) return None, error_payload if isinstance(async_result, ExecutionResult): if not async_result.errors: check.failed( f"Only expect non-async result on error, got {async_result}" ) error_payload = format_graphql_error( async_result.errors[0]) # type: ignore return None, error_payload # in the future we should get back async gen directly, back compat for now disposable, async_gen = _disposable_and_async_gen_from_obs( async_result, get_event_loop()) task = get_event_loop().create_task( _handle_async_results(async_gen, operation_id, websocket)) task.add_done_callback(lambda _: disposable.dispose()) return task, None
async def handle_start(self, message: OperationMessage) -> None: operation_id = message["id"] payload = cast(StartPayload, message["payload"]) query = payload["query"] operation_name = payload.get("operationName") variables = payload.get("variables") context = await self.get_context() root_value = await self.get_root_value() if self.debug: pretty_print_graphql_operation(operation_name, query, variables) try: result_source = await self.schema.subscribe( query=query, variable_values=variables, operation_name=operation_name, context_value=context, root_value=root_value, ) except GraphQLError as error: error_payload = format_graphql_error(error) await self.send_message(GQL_ERROR, operation_id, error_payload) self.schema.process_errors([error]) return if isinstance(result_source, GraphQLExecutionResult): assert result_source.errors error_payload = format_graphql_error(result_source.errors[0]) await self.send_message(GQL_ERROR, operation_id, error_payload) self.schema.process_errors(result_source.errors) return self.subscriptions[operation_id] = result_source result_handler = self.handle_async_results(result_source, operation_id) self.tasks[operation_id] = asyncio.create_task(result_handler)
async def handle_async_results( self, result_source: AsyncGenerator, operation_id: str, ) -> None: try: async for result in result_source: if result.errors: error_payload = [ format_graphql_error(err) for err in result.errors ] error_message = ErrorMessage(id=operation_id, payload=error_payload) await self.send_message(error_message) self.schema.process_errors(result.errors) return else: next_payload = {"data": result.data} next_message = NextMessage(id=operation_id, payload=next_payload) await self.send_message(next_message) except asyncio.CancelledError: # CancelledErrors are expected during task cleanup. return except Exception as error: # GraphQLErrors are handled by graphql-core and included in the # ExecutionResult error = GraphQLError(str(error), original_error=error) error_payload = [format_graphql_error(error)] error_message = ErrorMessage(id=operation_id, payload=error_payload) await self.send_message(error_message) self.schema.process_errors([error]) return await self.send_message(CompleteMessage(id=operation_id))
def dispatch(self, request, *args, **kwargs): if request.method.lower() not in ("get", "post"): return HttpResponseNotAllowed( ["GET", "POST"], "GraphQL only supports GET and POST requests.") if "text/html" in request.META.get("HTTP_ACCEPT", ""): return render( request, "graphql/playground.html", {"REQUEST_PATH": request.get_full_path()}, ) data = json.loads(request.body) try: query = data["query"] variables = data.get("variables") operation_name = data.get("operationName") except KeyError: return HttpResponseBadRequest( "No GraphQL query found in the request") context = {"request": request} result = graphql_sync( self.schema, query, variable_values=variables, context_value=context, operation_name=operation_name, ) response_data = {"data": result.data} if result.errors: response_data["errors"] = [ format_graphql_error(err) for err in result.errors ] self._capture_sentry_exceptions(result.errors) return JsonResponse(response_data, status=200)
def format_error(error): if isinstance(error, GraphQLError): result = format_graphql_error(error) else: result = {"message": str(error)} exc = error while isinstance(exc, GraphQLError) and hasattr(exc, "original_error"): exc = exc.original_error logger.error("Exception information:", exc_info=exc) if settings.DEBUG: lines = [] for line in traceback.format_exception(type(exc), exc, exc.__traceback__): lines.extend(line.rstrip().splitlines()) result["extensions"] = { "exception": {"code": type(exc).__name__, "stacktrace ": lines} } return result
def format_error(original_error): error = getattr(original_error, 'original_error', original_error) # sentry_sdk.capture_exception(original_error) if isinstance(original_error, GraphQLLocatedError) or isinstance( original_error, GraphQLError): if isinstance(error, ValidationError): return format_internal_error(error, code=400) if isinstance(error, GrapheneDjangoJWTBaseException): return format_internal_error(error) if settings.DEBUG: return format_internal_error(error) else: return format_internal_error(BaseException()) if isinstance(error, GraphQLSyntaxError): return format_graphql_error(error) else: if settings.DEBUG: return format_internal_error(error) else: return format_internal_error(BaseException())
def dispatch(self, request, *args, **kwargs): if request.method.lower() not in ("get", "post"): return HttpResponseNotAllowed( ["GET", "POST"], "GraphQL only supports GET and POST requests.") if "text/html" in request.META.get("HTTP_ACCEPT", ""): if not self.graphiql: raise Http404("GraphiQL has been disabled") return self._render_graphiql(request) data = json.loads(request.body) try: query = data["query"] variables = data.get("variables") operation_name = data.get("operationName") except KeyError: return HttpResponseBadRequest( "No GraphQL query found in the request") context = {"request": request} result = graphql_sync( self.schema, query, root_value=self.get_root_value(), variable_values=variables, context_value=context, operation_name=operation_name, ) response_data = {"data": result.data} if result.errors: response_data["errors"] = [ format_graphql_error(err) for err in result.errors ] return JsonResponse(response_data)
def format_error(error): if isinstance(error, GraphQLError): result = format_graphql_error(error) else: result = {'message': str(error)} if settings.DEBUG: exc = error while (isinstance(exc, GraphQLError) and hasattr(exc, 'original_error')): exc = exc.original_error lines = [] for line in traceback.format_exception(type(exc), exc, exc.__traceback__): lines.extend(line.rstrip().splitlines()) result['extensions'] = { 'exception': { 'code': type(exc).__name__, 'stacktrace ': lines } } return result
def dispatch_request(self): if "text/html" in request.environ.get("HTTP_ACCEPT", ""): if not self.graphiql: abort(404) template = render_graphiql_page() return self.render_template(request, template=template) data = request.json try: query = data["query"] variables = data.get("variables") operation_name = data.get("operationName") except KeyError: return Response("No valid query was provided for the request", 400) context = {"request": request} result = self.schema.execute_sync( query, variable_values=variables, context_value=context, operation_name=operation_name, root_value=self.root_value, ) response_data = {"data": result.data} if result.errors: response_data["errors"] = [ format_graphql_error(err) for err in result.errors ] return Response( json.dumps(response_data), status=400 if result.errors else 200, content_type="application/json", )
def format_error(error): if isinstance(error, GraphQLLocatedError): error = error.original_error formatted_error = format_graphql_error(error) graphql_error = OrderedDict([('type', error.__class__.__name__)]) if extensions_settings.EXT_SHOW_ERROR_MESSAGE_HANDLER(error): graphql_error['message'] = formatted_error['message'] else: # Internal errors must be masked graphql_error['message'] = _('Internal server error') if isinstance(error, exceptions.GraphQLError): graphql_error['code'] = error.code if error.error_data: graphql_error['data'] = error.error_data else: graphql_error['code'] = 'error' if 'location' in formatted_error: graphql_error['location'] = formatted_error['location'] if error.__traceback__ is not None: info = error.__traceback__.tb_frame.f_locals.get('info') if info is not None: graphql_error['path'] = [info.field_name] graphql_error['operation'] = info.operation.operation if settings.DEBUG: graphql_error['trace'] = traceback.format_list( traceback.extract_tb(error.__traceback__)) return graphql_error
def format_error(error): if isinstance(error, GraphQLError): return format_graphql_error(error) return {'message': six.text_type(error)}
def error_formatter(error): formatted = format_graphql_error(error) if hasattr(error, 'original_error'): if isinstance(error.original_error, GraphExecutionError): formatted['code'] = error.original_error.code return formatted
def handle_graphql_errors(self, errors): return [format_graphql_error(err) for err in errors]
def default_format_error(error): if isinstance(error, GraphQLError): return format_graphql_error(error) return {"message": str(error)}
def format_error(error): if isinstance(error, GraphQLError): return format_graphql_error(error) else: return {'message': str(error)}
def format_error(error): if isinstance(error, GraphQLError): return format_graphql_error(error) return {'message': '{}: {}'.format( error.__class__.__name__, six.text_type(error))}