Skip to content

Commit

Permalink
[EXCEPTIONS]: Default exception/error catcher
Browse files Browse the repository at this point in the history
  • Loading branch information
amadolid committed Oct 7, 2024
1 parent 23f499a commit 7cf41f0
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 10 deletions.
7 changes: 7 additions & 0 deletions jac-cloud/docs/Environment-Variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
| RESET_CODE_TIMEOUT | Password reset code expiration in hours | 24 |
| SENDGRID_HOST | Sendgrid host used for hyperlinking verification/reset code | http://localhost:8000 |
| SENDGRID_API_KEY | Sendgrid api key | null |
| LOGGER_NAME | Specified logger name | app |
| LOGGER_LEVEL | Control log level | debug |
| LOGGER_FILE_PATH | Log directory and name | /tmp/jac_cloud_logs/jac-cloud.log |
| LOGGER_ROLLOVER_INTERVAL | M = every minute, H = hourly, D = daily, W = weekly | D |
| LOGGER_MAX_BACKUP | Maximum number of backup files before it will deletes old file. Non positive value will not have maximum | -1 |
| LOGGER_ROLLOVER_MAX_FILE_SIZE | Maximum file size in bytes before it will rollover to new file | 10000000 |
| LOGGER_USE_UTC | If logger will use UTC | false |

# **SSO Supported Enviroment Variable**
## Supported Platform
Expand Down
26 changes: 22 additions & 4 deletions jac-cloud/jac_cloud/jaseci/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

from contextlib import asynccontextmanager
from os import getenv
from traceback import format_exception
from typing import Any, AsyncGenerator

from fastapi import FastAPI as _FaststAPI
from fastapi import FastAPI as _FaststAPI, Request
from fastapi.responses import ORJSONResponse

from uvicorn import run as _run

from .utils import Emailer
from .utils import Emailer, logger


class FastAPI:
Expand Down Expand Up @@ -63,6 +65,22 @@ async def lifespan(app: _FaststAPI) -> AsyncGenerator[None, _FaststAPI]:
for router in [healthz_router, sso_router, user_router, walker_router]:
cls.__app__.include_router(router)

@cls.__app__.exception_handler(Exception)
async def uncatched_exception_handler(
request: Request, exc: Exception
) -> ORJSONResponse:
"""Catched uncatched exceptions."""
response = {"errors": format_exception(exc)}

log: dict[str, Any] = {"request_url": str(request.url)}
log["extra_fields"] = list(log.keys())
logger.error(
f"Call from to {log["request_url"]} returns unexpected errors: {response["errors"]}",
extra=log,
)

return ORJSONResponse(response, status_code=500)

return cls.__app__

@classmethod
Expand All @@ -71,7 +89,7 @@ def start(
host: str | None = None,
port: int | None = None,
emailer: type[Emailer] | None = None,
**kwargs: Any # noqa ANN401
**kwargs: Any, # noqa ANN401
) -> None:
"""Run FastAPI Handler via Uvicorn."""
if emailer:
Expand All @@ -81,5 +99,5 @@ def start(
cls.get(),
host=host or getenv("HOST") or "0.0.0.0",
port=port or int(getenv("PORT", "8000")),
**kwargs
**kwargs,
)
3 changes: 2 additions & 1 deletion jac-cloud/jac_cloud/jaseci/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from random import choice
from string import ascii_letters, digits

from .logger import log_entry, log_exit, logger
from .logger import log_dumps, log_entry, log_exit, logger
from .mail import Emailer, SendGridEmailer


Expand All @@ -29,6 +29,7 @@ def utc_timestamp(**addons: int) -> int:
"random_string",
"utc_datetime",
"utc_timestamp",
"log_dumps",
"log_entry",
"log_exit",
"logger",
Expand Down
15 changes: 10 additions & 5 deletions jac-cloud/jac_cloud/jaseci/utils/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,23 +252,28 @@ class Level(IntEnum):

handler = MixedTimedRotatingFileHandler(
getenv("LOGGER_FILE_PATH", "/tmp/jac_cloud_logs/jac-cloud.log"),
when=getenv("LOGGER_TIME_INTERVAL", "d"),
backup_count=int(getenv("LOGGER_MAX_BACKUP", "5")),
max_bytes=int(getenv("LOGGER_MAX_FILE_SIZE", "10000000")),
when=getenv("LOGGER_ROLLOVER_INTERVAL", "d"),
backup_count=int(getenv("LOGGER_MAX_BACKUP", "-1")),
max_bytes=int(getenv("LOGGER_ROLLOVER_MAX_FILE_SIZE", "10000000")),
utc=getenv("LOGGER_USE_UTC") == "true",
)
handler.setFormatter(StdlibFormatter())
logger.addHandler(handler)


def log_dumps(payload: dict[str, Any] | list[Any]) -> str:
"""Dump dictionary log."""
return dumps(payload, separators=DEFAULT_SEPARATORS)


def log_entry(
api: str, caller: str | None, payload: dict[str, Any], node: str | None = None
) -> dict[str, Any]:
"""Log metadata on entry."""
log: dict[str, Any] = {
"api_name": api,
"caller_name": caller,
"payload": dumps(payload, separators=DEFAULT_SEPARATORS),
"payload": log_dumps(payload),
"entry_node": node,
}
msg = str(
Expand All @@ -286,7 +291,7 @@ def log_entry(
def log_exit(response: dict[str, Any], log: dict[str, Any] | None = None) -> None:
"""Log metadata on exit."""
log = log or {}
log["api_response"] = dumps(response, separators=DEFAULT_SEPARATORS)
log["api_response"] = log_dumps(response)
log["extra_fields"] = list(log.keys())
log_msg = str(
f"Returning call from {log["caller_name"]}"
Expand Down

0 comments on commit 7cf41f0

Please sign in to comment.