diff options
Diffstat (limited to 'gn_auth/errors/common.py')
| -rw-r--r-- | gn_auth/errors/common.py | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/gn_auth/errors/common.py b/gn_auth/errors/common.py new file mode 100644 index 0000000..8dc0373 --- /dev/null +++ b/gn_auth/errors/common.py @@ -0,0 +1,58 @@ +"""Common utilities.""" +import logging +import traceback +from typing import Callable + +from flask import request, Response, make_response, render_template + +logger = logging.getLogger(__name__) + + +def add_trace(exc: Exception, errobj: dict) -> dict: + """Add the traceback to the error handling object.""" + return { + **errobj, + "error-trace": "".join(traceback.format_exception(exc)) + } + +def __status_code__(exc: Exception): + """Fetch the error code for exceptions that have them.""" + error_code_attributes = ( + "code", "error_code", "errorcode", "status_code", "status_code") + for attr in error_code_attributes: + if hasattr(exc, attr): + return getattr(exc, attr) + + return 500 + + +def build_handler(description: str) -> Callable[[Exception], Response]: + """Generic utility to build error handlers.""" + def __handler__(exc: Exception) -> Response: + """Handle the exception as appropriate for requests of different mimetypes.""" + error = (exc.name if hasattr(exc, "name") else exc.__class__.__name__) + status_code = __status_code__(exc) + content_type = request.content_type + if bool(content_type) and content_type.lower() == "application/json": + return make_response(( + add_trace( + exc, + { + "requested-uri": request.url, + "error": error, + "error_description": description + }), + status_code, + {"Content-Type": "application/json"})) + + return make_response(( + render_template( + f"http-error-{str(status_code)[0:-2]}xx.html", + error=exc, + page=request.url, + description=description, + trace=traceback.format_exception(exc)), + status_code, + {"Content-Type": "text/html"})) + + return __handler__ |
