Skip to content

Commit 725cf11

Browse files
authored
Add compatibility with http-errors to jsonapi_exception_formatter (#2)
* Add compatibility with http-errors to jsonapi_exception_formatter and add unauthorized exception
1 parent a4bac73 commit 725cf11

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

flask_rest_jsonapi/decorators.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from flask import request, make_response, jsonify, current_app
77

8-
from flask_rest_jsonapi.errors import jsonapi_errors
8+
from flask_rest_jsonapi.errors import jsonapi_errors, format_http_exception
99
from flask_rest_jsonapi.exceptions import JsonApiException
1010
from flask_rest_jsonapi.utils import JSONEncoder
1111

@@ -77,6 +77,12 @@ def wrapper(*args, **kwargs):
7777
e.status,
7878
headers)
7979
except Exception as e:
80+
api_ex = format_http_exception(e)
81+
if api_ex:
82+
return make_response(jsonify(jsonapi_errors([api_ex.to_dict()])),
83+
api_ex.status,
84+
headers)
85+
8086
if current_app.config['DEBUG'] is True:
8187
raise e
8288

flask_rest_jsonapi/errors.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
"""Helper to format Api errors according to jsonapi specification"""
2+
from flask_rest_jsonapi.exceptions import BadRequest, ObjectNotFound, InvalidType, AccessDenied, Unauthorized
3+
4+
STATUS_MAP = {
5+
400: BadRequest,
6+
401: Unauthorized,
7+
404: ObjectNotFound,
8+
409: InvalidType,
9+
403: AccessDenied,
10+
}
211

312

413
def jsonapi_errors(jsonapi_errors):
@@ -9,3 +18,23 @@ def jsonapi_errors(jsonapi_errors):
918
"""
1019
return {'errors': [jsonapi_error for jsonapi_error in jsonapi_errors],
1120
'jsonapi': {'version': '1.0'}}
21+
22+
23+
def format_http_exception(ex):
24+
"""
25+
try to format http exception to jsonapi 1.0
26+
Warning! It only works for errors with status code less than 500
27+
:param ex: http exception
28+
:return:
29+
"""
30+
code = getattr(ex, 'code', None)
31+
try:
32+
status = int(code)
33+
except TypeError:
34+
return
35+
36+
api_ex = STATUS_MAP.get(status)
37+
if not api_ex:
38+
return
39+
40+
return api_ex(detail=getattr(ex, 'description', ''))

flask_rest_jsonapi/exceptions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ class InvalidType(JsonApiException):
9898
status = '409'
9999

100100

101+
class Unauthorized(JsonApiException):
102+
"""Throw this error if the user is not authorized"""
103+
104+
title = 'Unauthorized'
105+
status = '401'
106+
107+
101108
class AccessDenied(JsonApiException):
102109
"""Throw this error when requested resource owner doesn't match the user of the ticket"""
103110

0 commit comments

Comments
 (0)