|
| 1 | +"""Module for the global FHIR API exception handler""" |
| 2 | +import functools |
| 3 | +import uuid |
| 4 | +from typing import Callable, Type |
| 5 | + |
| 6 | +from clients import logger |
| 7 | +from constants import GENERIC_SERVER_ERROR_DIAGNOSTICS_MESSAGE |
| 8 | +from controller.aws_apig_response_utils import create_response |
| 9 | +from models.errors import UnauthorizedVaxError, UnauthorizedError, ResourceNotFoundError, create_operation_outcome, \ |
| 10 | + Severity, Code |
| 11 | + |
| 12 | + |
| 13 | +_CUSTOM_EXCEPTION_TO_STATUS_MAP: dict[Type[Exception], int] = { |
| 14 | + UnauthorizedError: 403, |
| 15 | + UnauthorizedVaxError: 403, |
| 16 | + ResourceNotFoundError: 404 |
| 17 | +} |
| 18 | + |
| 19 | + |
| 20 | +def fhir_api_exception_handler(function: Callable) -> Callable: |
| 21 | + """Decorator to handle any expected FHIR API exceptions or unexpected exception and provide a valid response to |
| 22 | + the client""" |
| 23 | + |
| 24 | + @functools.wraps(function) |
| 25 | + def wrapper(*args, **kwargs): |
| 26 | + try: |
| 27 | + return function(*args, **kwargs) |
| 28 | + except tuple(_CUSTOM_EXCEPTION_TO_STATUS_MAP) as exc: |
| 29 | + status_code = _CUSTOM_EXCEPTION_TO_STATUS_MAP[type(exc)] |
| 30 | + return create_response(status_code=status_code, body=exc.to_operation_outcome()) |
| 31 | + except Exception: # pylint: disable = broad-exception-caught |
| 32 | + logger.exception("Unhandled exception") |
| 33 | + server_error = create_operation_outcome( |
| 34 | + resource_id=str(uuid.uuid4()), |
| 35 | + severity=Severity.error, |
| 36 | + code=Code.server_error, |
| 37 | + diagnostics=GENERIC_SERVER_ERROR_DIAGNOSTICS_MESSAGE, |
| 38 | + ) |
| 39 | + return create_response(500, server_error) |
| 40 | + |
| 41 | + return wrapper |
| 42 | + |
0 commit comments