54 Zeilen
1.6 KiB
Python
54 Zeilen
1.6 KiB
Python
import time
|
|
import uuid
|
|
from typing import Optional
|
|
from flask import request, g
|
|
from werkzeug.exceptions import HTTPException
|
|
|
|
from core.exceptions import BaseApplicationException
|
|
from core.monitoring import track_error
|
|
from core.logging_config import get_logger
|
|
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
class ErrorHandlingMiddleware:
|
|
def __init__(self, app=None):
|
|
self.app = app
|
|
if app:
|
|
self.init_app(app)
|
|
|
|
def init_app(self, app):
|
|
app.before_request(self._before_request)
|
|
app.teardown_appcontext(self._teardown_request)
|
|
|
|
def _before_request(self):
|
|
g.request_id = request.headers.get('X-Request-ID', str(uuid.uuid4()))
|
|
g.start_time = time.time()
|
|
g.errors = []
|
|
|
|
def _teardown_request(self, exception=None):
|
|
if exception:
|
|
self._handle_exception(exception)
|
|
|
|
if hasattr(g, 'errors') and g.errors:
|
|
for error in g.errors:
|
|
if isinstance(error, BaseApplicationException):
|
|
track_error(error)
|
|
|
|
def _handle_exception(self, exception):
|
|
if isinstance(exception, BaseApplicationException):
|
|
track_error(exception)
|
|
elif isinstance(exception, HTTPException):
|
|
pass
|
|
else:
|
|
logger.error(
|
|
f"Unhandled exception: {type(exception).__name__}",
|
|
exc_info=True,
|
|
extra={
|
|
'request_id': getattr(g, 'request_id', 'unknown'),
|
|
'endpoint': request.endpoint,
|
|
'method': request.method,
|
|
'path': request.path
|
|
}
|
|
) |