Coverage for api/errors.py: 26%
65 statements
« prev ^ index » next coverage.py v7.6.2, created at 2024-10-10 03:02 +0300
« prev ^ index » next coverage.py v7.6.2, created at 2024-10-10 03:02 +0300
1import logging
2import traceback
3from functools import wraps
5from config import LOG_LEVEL
6from fastapi import HTTPException, Request
7from fastapi.responses import JSONResponse
8from jose.exceptions import ExpiredSignatureError
9from logging_config import logger
10from pydantic_core import ValidationError
11from services.telegram import group_notification
12from sotrans_fastapi_keycloak import KeycloakError
15def log_error(add_text=""):
16 if LOG_LEVEL > logging.ERROR:
17 return
18 err = traceback.format_exc()
19 if add_text:
20 err += f"\n\n{add_text}"
21 logger.error(err)
22 group_notification(err, logging.ERROR)
25def log_warning(add_text=""):
26 if LOG_LEVEL > logging.WARNING:
27 return
28 err = traceback.format_exc()
29 if err == "NoneType: None\n":
30 err = ""
31 if add_text:
32 err += f"\n\n{add_text}"
33 logger.warning(err)
34 group_notification(err, logging.WARNING)
37def error_handler(func):
38 @wraps(func)
39 async def wrapped(*args, **kwargs):
40 try:
41 result = await func(*args, **kwargs)
42 return result
43 except Exception:
44 log_error()
46 return wrapped
49def endpoint_error_handler(func):
50 @wraps(func)
51 async def wrapped(*args, **kwargs):
52 try:
53 result = await func(*args, **kwargs)
54 return result
55 except HTTPException as e:
56 raise e
57 except ValidationError as e:
58 raise HTTPException(status_code=422, detail=str(e))
59 except KeycloakError as e:
60 keycloak_error_handler(None, e)
61 except ExpiredSignatureError as e:
62 logger.info("HERE")
63 raise HTTPException(status_code=401, detail=str(e))
64 except Exception:
65 log_error()
66 raise HTTPException(
67 status_code=500, detail={"error": traceback.format_exc()}
68 )
70 return wrapped
73def keycloak_error_handler(request: Request | None, exc: KeycloakError):
74 return JSONResponse(
75 status_code=exc.status_code,
76 content={"сообщение": exc.reason},
77 )
80def app_error_handler(request: Request | None, exc: Exception):
81 match exc:
82 case ExpiredSignatureError(): # type: ignore[misc]
83 return JSONResponse(
84 status_code=401,
85 content={"message": str(exc)},
86 )
87 case _:
88 return JSONResponse(
89 status_code=500,
90 content={"message": str(exc)},
91 )