Skip to content

Commit

Permalink
feat: Tidy up api errors, register on api directly
Browse files Browse the repository at this point in the history
  • Loading branch information
bdewilde committed Dec 15, 2023
1 parent 53e8bc5 commit 256c7f6
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 43 deletions.
2 changes: 0 additions & 2 deletions colandr/apis/api_v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@


from .auth import ns as ns_auth
from .errors import ns as ns_errors
from .health import ns as ns_health
from .resources.citation_imports import ns as ns_citation_imports
from .resources.citation_screenings import ns as ns_citation_screenings
Expand All @@ -42,7 +41,6 @@


api_v1.add_namespace(ns_auth)
api_v1.add_namespace(ns_errors)
api_v1.add_namespace(ns_health)
api_v1.add_namespace(ns_swagger)
api_v1.add_namespace(ns_users)
Expand Down
85 changes: 44 additions & 41 deletions colandr/apis/errors.py
Original file line number Diff line number Diff line change
@@ -1,65 +1,59 @@
from typing import Optional

import webargs.core
import webargs.flaskparser
from flask import current_app, jsonify
from flask_restx import Namespace
from flask import current_app
from werkzeug import exceptions
from werkzeug.http import HTTP_STATUS_CODES


ns = Namespace("errors")
from .api_v1 import api_v1


@ns.errorhandler
def default_error(error):
message = f"an unhandled exception occurred: {error}"
@api_v1.errorhandler(exceptions.HTTPException)
def http_error(error):
message = error.description
current_app.logger.exception(message)
response = jsonify({"message": message})
response.status_code = getattr(error, "code", 500)
return response
return _make_error_response(error.code, message)


@ns.errorhandler(exceptions.BadRequest)
@api_v1.errorhandler(exceptions.BadRequest)
def bad_request_error(error):
message = str(error)
current_app.logger.error(message)
response = jsonify({"message": message})
response.status_code = 400
return response
return _make_error_response(400, message)


@ns.errorhandler(exceptions.Unauthorized)
@api_v1.errorhandler(exceptions.Unauthorized)
def unauthorized_error(error):
message = str(error)
current_app.logger.error(message)
response = jsonify({"message": message})
response.status_code = 401
return response
return _make_error_response(401, message)


@ns.errorhandler(exceptions.Forbidden)
@api_v1.errorhandler(exceptions.Forbidden)
def forbidden_error(error):
message = str(error)
current_app.logger.error(message)
response = jsonify({"message": message})
response.status_code = 403
return response
return _make_error_response(403, message)


@ns.errorhandler(exceptions.NotFound)
@api_v1.errorhandler(exceptions.NotFound)
def not_found_error(error):
message = str(error)
current_app.logger.error(message)
response = jsonify({"message": message})
response.status_code = 404
return response
return _make_error_response(404, message)


@ns.errorhandler(exceptions.InternalServerError)
@api_v1.errorhandler(exceptions.InternalServerError)
def internal_server_error(error):
message = str(error)
current_app.logger.exception(message)
return _make_error_response(500, message)


def db_integrity_error(message):
current_app.logger.error(message)
response = jsonify({"message": message})
response.status_code = 500
return response
return _make_error_response(422, message)


@webargs.flaskparser.parser.error_handler
Expand All @@ -72,14 +66,23 @@ def validation_error(error, req, schema, *, error_status_code, error_headers):
See: webargs/issues/181
"""
status_code = error_status_code or webargs.core.DEFAULT_VALIDATION_STATUS
webargs.flaskparser.abort(
status_code,
exc=error,
messages=error.messages,
)


def db_integrity_error(message):
response = jsonify({"message": message})
response.status_code = 422
return response
webargs.flaskparser.abort(status_code, exc=error, messages=error.messages)


def _make_error_response(
status_code: int, message: Optional[str] = None
) -> tuple[dict[str, str], int]:
data = {"error": HTTP_STATUS_CODES.get(status_code, "Unknown error")}
if message:
data["message"] = message
return (data, status_code)


# TODO: do we need this?
# @api_v1.errorhandler
# def default_error(error):
# message = f"an unhandled exception occurred: {error}"
# current_app.logger.exception(message)
# response = jsonify({"message": message})
# response.status_code = getattr(error, "code", 500)
# return response

0 comments on commit 256c7f6

Please sign in to comment.