Skip to content

Commit

Permalink
Add compatibility with http-errors to jsonapi_exception_formatter (#2)
Browse files Browse the repository at this point in the history
* Add compatibility with http-errors to jsonapi_exception_formatter and add unauthorized exception
  • Loading branch information
pysalt authored Apr 2, 2020
1 parent a4bac73 commit 725cf11
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
8 changes: 7 additions & 1 deletion flask_rest_jsonapi/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from flask import request, make_response, jsonify, current_app

from flask_rest_jsonapi.errors import jsonapi_errors
from flask_rest_jsonapi.errors import jsonapi_errors, format_http_exception
from flask_rest_jsonapi.exceptions import JsonApiException
from flask_rest_jsonapi.utils import JSONEncoder

Expand Down Expand Up @@ -77,6 +77,12 @@ def wrapper(*args, **kwargs):
e.status,
headers)
except Exception as e:
api_ex = format_http_exception(e)
if api_ex:
return make_response(jsonify(jsonapi_errors([api_ex.to_dict()])),
api_ex.status,
headers)

if current_app.config['DEBUG'] is True:
raise e

Expand Down
29 changes: 29 additions & 0 deletions flask_rest_jsonapi/errors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
"""Helper to format Api errors according to jsonapi specification"""
from flask_rest_jsonapi.exceptions import BadRequest, ObjectNotFound, InvalidType, AccessDenied, Unauthorized

STATUS_MAP = {
400: BadRequest,
401: Unauthorized,
404: ObjectNotFound,
409: InvalidType,
403: AccessDenied,
}


def jsonapi_errors(jsonapi_errors):
Expand All @@ -9,3 +18,23 @@ def jsonapi_errors(jsonapi_errors):
"""
return {'errors': [jsonapi_error for jsonapi_error in jsonapi_errors],
'jsonapi': {'version': '1.0'}}


def format_http_exception(ex):
"""
try to format http exception to jsonapi 1.0
Warning! It only works for errors with status code less than 500
:param ex: http exception
:return:
"""
code = getattr(ex, 'code', None)
try:
status = int(code)
except TypeError:
return

api_ex = STATUS_MAP.get(status)
if not api_ex:
return

return api_ex(detail=getattr(ex, 'description', ''))
7 changes: 7 additions & 0 deletions flask_rest_jsonapi/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ class InvalidType(JsonApiException):
status = '409'


class Unauthorized(JsonApiException):
"""Throw this error if the user is not authorized"""

title = 'Unauthorized'
status = '401'


class AccessDenied(JsonApiException):
"""Throw this error when requested resource owner doesn't match the user of the ticket"""

Expand Down

0 comments on commit 725cf11

Please sign in to comment.