Skip to content

Commit 42e8606

Browse files
authored
Adding error to datadog span (#2080)
1 parent 57caacf commit 42e8606

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

src/infrastructure/dependency/structured_logs.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,11 @@ async def dispatch(self, request: Request, call_next) -> Response:
187187

188188
try:
189189
response = await call_next(request)
190-
except Exception:
190+
except Exception as exc:
191191
structlog.stdlib.get_logger("api.error").exception("Unhandled exception")
192-
192+
span = tracer.current_span()
193+
if span:
194+
span.set_exc_info(type(exc), exc, exc.__traceback__)
193195
finally:
194196
access_logger = structlog.stdlib.get_logger("api.access")
195197
process_time = time.perf_counter_ns() - start_time

src/infrastructure/http/exceptions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from asyncpg import InvalidPasswordError
2+
from ddtrace import tracer
23
from fastapi.encoders import jsonable_encoder
34
from fastapi.exception_handlers import http_exception_handler
45
from fastapi.exceptions import RequestValidationError
@@ -14,10 +15,17 @@
1415
from infrastructure.logger import logger
1516

1617

18+
def _set_trace_exception(exc: Exception) -> None:
19+
span = tracer.current_span()
20+
if span:
21+
span.set_exc_info(type(exc), exc, exc.__traceback__)
22+
23+
1724
def custom_base_errors_handler(_: Request, error: BaseError) -> JSONResponse:
1825
"""This function is called if the BaseError was raised."""
1926

2027
logger.error(error.error, exc_info=error)
28+
_set_trace_exception(error)
2129

2230
response = ErrorResponseMulti(
2331
result=[
@@ -77,6 +85,7 @@ def python_base_error_handler(_: Request, error: Exception) -> JSONResponse:
7785
response = ErrorResponseMulti(result=[ErrorResponse(message=f"Unhandled error: {error_message}")])
7886

7987
logger.error(error_message, exc_info=error)
88+
_set_trace_exception(error)
8089

8190
return JSONResponse(
8291
content=jsonable_encoder(response.model_dump(by_alias=True)),
@@ -90,6 +99,9 @@ def pydantic_validation_errors_handler(request: Request, error: RequestValidatio
9099
this_logger = logger.bind(
91100
error_location={"file": error.endpoint_file, "line": error.endpoint_line, "function": error.endpoint_function}
92101
)
102+
103+
_set_trace_exception(error)
104+
93105
for err in error.errors():
94106
if isinstance(err, dict):
95107
message = err["msg"]
@@ -118,6 +130,8 @@ def sqlalchemy_database_error_handler(
118130
) -> JSONResponse:
119131
"""This function is called if the SQLAlchemy database error was raised."""
120132
logger.error(str(error), exc_info=error)
133+
_set_trace_exception(error)
134+
121135
response = ErrorResponseMulti(result=[ErrorResponse(message="Internal server error")])
122136

123137
return JSONResponse(

0 commit comments

Comments
 (0)