Skip to content

Commit 58e5053

Browse files
mairasalazarslint
authored andcommitted
refactor: implement logging for errors
1 parent af775dc commit 58e5053

2 files changed

Lines changed: 47 additions & 9 deletions

File tree

app/main.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@
33

44
"""FastAPI application entry point with multi-tenant auth."""
55

6+
import logging
67
from contextlib import asynccontextmanager
78

8-
from fastapi import Depends, FastAPI
9+
from fastapi import Depends, FastAPI, Request
10+
from fastapi.exception_handlers import (
11+
http_exception_handler,
12+
request_validation_exception_handler,
13+
)
14+
from fastapi.exceptions import RequestValidationError
915
from fastapi.middleware.cors import CORSMiddleware
16+
from starlette.exceptions import HTTPException as StarletteHTTPException
1017
from temporalio.client import Client
1118
from temporalio.contrib.pydantic import pydantic_data_converter
1219

@@ -16,6 +23,8 @@
1623
from .routers import workflows
1724
from .tenants import TenantRegistry
1825

26+
logger = logging.getLogger(__name__)
27+
1928

2029
@asynccontextmanager
2130
async def lifespan(app: FastAPI):
@@ -52,6 +61,32 @@ async def lifespan(app: FastAPI):
5261
allow_headers=["*"],
5362
)
5463

64+
65+
@app.exception_handler(StarletteHTTPException)
66+
async def custom_http_exception_handler(request, exc):
67+
"""Custom error handling for logging HTTP errors."""
68+
logger.warning(
69+
"HTTP %s on %s %s: %s",
70+
exc.status_code,
71+
request.method,
72+
request.url.path,
73+
exc.detail,
74+
)
75+
return await http_exception_handler(request, exc)
76+
77+
78+
@app.exception_handler(RequestValidationError)
79+
async def validation_exception_handler(request: Request, exc: RequestValidationError):
80+
"""Custom error handling for logging the Pydantic validation errors."""
81+
logger.warning(
82+
"Validation error on %s %s: %s",
83+
request.method,
84+
request.url.path,
85+
exc.errors(),
86+
)
87+
return await request_validation_exception_handler(request, exc)
88+
89+
5590
app.include_router(workflows.router)
5691

5792

app/routers/workflows.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"""Workflow API routes with tenant-scoped access control."""
55

66
import asyncio
7+
import logging
78
from typing import Any
89

910
from fastapi import APIRouter, Depends, HTTPException, Request
@@ -20,6 +21,8 @@
2021
from app.workflows.registry import get_workflow_spec
2122
from app.workflows.specs import WorkflowContext
2223

24+
logger = logging.getLogger(__name__)
25+
2326
router = APIRouter(
2427
prefix="/workflows",
2528
tags=["workflows"],
@@ -108,8 +111,8 @@ async def create(
108111
session.add(workflow)
109112
session.commit()
110113
workflow_id = workflow.public_id
111-
except SQLAlchemyError as e:
112-
print("Error(create)", e)
114+
except SQLAlchemyError:
115+
logger.exception("Error creating workflow")
113116
raise HTTPException(status_code=500, detail="Could not create workflow")
114117

115118
try:
@@ -126,8 +129,8 @@ async def create(
126129
id=f"{spec.id_prefix}-{workflow_id}",
127130
task_queue=spec.task_queue,
128131
)
129-
except Exception as e:
130-
print("Error(start_temporal_workflow)", e)
132+
except Exception:
133+
logger.exception("Error starting Temporal workflow")
131134
try:
132135
workflow.status = WorkflowStatus.ERROR
133136
session.commit()
@@ -153,8 +156,8 @@ async def read(
153156
workflow = session.exec(
154157
select(Workflow).where(Workflow.public_id == workflow_id)
155158
).one()
156-
except SQLAlchemyError as e:
157-
print("Error(read)", e)
159+
except SQLAlchemyError:
160+
logger.exception("Error reading workflow")
158161
raise HTTPException(status_code=404, detail="Workflow not found")
159162

160163
verify_tenant_owns_workflow(auth, workflow)
@@ -178,8 +181,8 @@ async def workflow_event(request: Request, workflow_id: str):
178181

179182
if status == "ERROR" or status == "SUCCESS":
180183
break
181-
except SQLAlchemyError as e:
182-
print("Error(stream)", e)
184+
except SQLAlchemyError:
185+
logger.exception("Error streaming workflow status")
183186
raise HTTPException(status_code=500)
184187

185188
await asyncio.sleep(STREAM_DELAY)

0 commit comments

Comments
 (0)