8000 Abstracted HttpError exceptions · graphql-python/flask-graphql@c3c9ad4 · GitHub
[go: up one dir, main page]

Skip to content

Commit c3c9ad4

Browse files
committed
Abstracted HttpError exceptions
1 parent 3372a7b commit c3c9ad4

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

flask_graphql/graphqlview.py

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from promise import Promise
23

34
import six
45
from flask import Response, request
@@ -16,10 +17,12 @@
1617

1718

1819
class HttpError(Exception):
19-
def __init__(self, response, message=None, *args, **kwargs):
20-
self.response = response
21-
self.message = message = message or response.description
22-
super(HttpError, self).__init__(message, *args, **kwargs)
20+
def __init__(self, status_code, message=None, is_graphql_error=False, headers=None):
21+
self.status_code = status_code
22+
self.message = message
23+
self.is_graphql_error = is_graphql_error
24+
self.headers = headers
25+
super(HttpError, self).__init__(message)
2326

2427

2528
class GraphQLView(View):
@@ -42,7 +45,6 @@ def __init__(self, **kwargs):
4245
if hasattr(self, key):
4346
setattr(self, key, value)
4447

45-
assert not all((self.graphiql, self.batch)), 'Use either graphiql or batch processing'
4648
assert isinstance(self.schema, GraphQLSchema), 'A Schema is required to be provided to GraphQLView.'
4749

4850
# noinspection PyUnusedLocal
@@ -70,27 +72,39 @@ def render_graphiql(self, **kwargs):
7072
def dispatch_request(self):
7173
try:
7274
if request.method.lower() not in ('get', 'post'):
73-
raise HttpError(MethodNotAllowed(['GET', 'POST'], 'GraphQL only supports GET and POST requests.'))
75+
raise HttpError(
76+
405,
77+
'GraphQL only supports GET and POST requests.',
78+
headers={
79+
'Allow': ['GET, POST']
80+
}
81+
)
7482

7583
data = self.parse_body(request)
7684

7785
show_graphiql = self.graphiql and self.can_display_graphiql(data)
7886

79-
if isinstance(data, list):
87+
is_batch = isinstance(data, list)
88+
if is_batch:
8089
if not self.batch or show_graphiql:
81-
raise HttpError(BadRequest('Batch requests are not allowed.'))
82-
83-
responses = [self.get_response(request, entry) for entry in data]
84-
response, status_codes = zip(*responses)
85-
status_code = max(status_codes)
90+
raise HttpError(
91+
400,
92+
'Batch requests are not allowed.'
93+
)
8694
else:
87-
response, status_code = self.get_response(request, data, show_graphiql)
95+
data = [data]
96+
responses = [self.get_response(request, entry, show_graphiql) for entry in data]
97+
response, status_codes = zip(*responses)
98+
status_code = max(status_codes)
99+
100+
if not is_batch:
101+
response = response[0]
88102

89103
pretty = self.pretty or show_graphiql or request.args.get('pretty')
90104
result = self.json_encode(response, pretty)
91105

92106
if show_graphiql:
93-
query, variables, operation_name, id = self.get_graphql_params(request, data)
107+
query, variables, operation_name, id = self.get_graphql_params(request, data[0])
94108
return self.render_graphiql(
95109
query=query,
96110
variables=variables,
@@ -109,22 +123,23 @@ def dispatch_request(self):
109123
self.json_encode({
110124
'errors': [self.format_error(e)]
111125
}),
112-
status=e.response.code,
113-
headers={'Allow': ['GET, POST']},
126+
status=e.status_code,
127+
headers=e.headers,
114128
content_type='application/json'
115129
)
116130

117131
def get_response(self, request, data, show_graphiql=False):
118132
query, variables, operation_name, id = self.get_graphql_params(request, data)
119-
120133
execution_result = self.execute_graphql_request(
121134
data,
122135
query,
123136
variables,
124137
operation_name,
125138
show_graphiql
126139
)
140+
return self.format_execution_result(execution_result, id)
127141

142+
def format_execution_result(self, execution_result, id):
128143
status_code = 200
129144
if execution_result:
130145
response = {}
@@ -164,7 +179,10 @@ def parse_body(self, request):
164179
try:
165180
return json.loads(request.data.decode('utf8'))
166181
except:
167-
raise HttpError(BadRequest('POST body sent invalid JSON.'))
182+
raise HttpError(
183+
400,
184+
'POST body sent invalid JSON.'
185+
)
168186

169187
elif content_type == 'application/x-www-form-urlencoded':
170188
return request.form
@@ -181,7 +199,7 @@ def execute_graphql_request(self, data, query, variables, operation_name, show_g
181199
if not query:
182200
if show_graphiql:
183201
return None
184-
raise HttpError(BadRequest('Must provide query string.'))
202+
raise HttpError(400, 'Must provide query string.')
185203

186204
try:
187205
source = Source(query, name='GraphQL request')
@@ -200,9 +218,13 @@ def execute_graphql_request(self, data, query, variables, operation_name, show_g
200218
if operation_ast and operation_ast.operation != 'query':
201219
if show_graphiql:
202220
return None
203-
raise HttpError(MethodNotAllowed(
204-
['POST'], 'Can only perform a {} operation from a POST request.'.format(operation_ast.operation)
205-
))
221+
raise HttpError(
222+
405,
223+
'Can only perform a {} operation from a POST request.'.format(operation_ast.operation),
224+
headers={
225+
'Allow': ['POST'],
226+
}
227+
)
206228

207229
try:
208230
return self.execute(
@@ -234,13 +256,13 @@ def request_wants_html(cls, request):
234256
def get_graphql_params(request, data):
235257
query = request.args.get('query') or data.get('query')
236258
variables = request.args.get('variables') or data.get('variables')
237-
id = request.args.get('id') or data.get('id')
259+
id = data.get('id')
238260

239261
if variables and isinstance(variables, six.text_type):
240262
try:
241263
variables = json.loads(variables)
242264
except:
243-
raise HttpError(BadRequest('Variables are invalid JSON.'))
265+
raise HttpError(400, 'Variables are invalid JSON.')
244266

245267
operation_name = request.args.get('operationName') or data.get('operationName')
246268

0 commit comments

Comments
 (0)
0