Skip to content

Commit

Permalink
Optimize exception info opera log record
Browse files Browse the repository at this point in the history
  • Loading branch information
wu-clan committed Sep 9, 2024
1 parent 90b2cca commit 4a9119c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 49 deletions.
2 changes: 1 addition & 1 deletion backend/app/admin/service/login_log_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ async def create(
)
await login_log_dao.create(db, obj_in)
except Exception as e:
log.exception(f'登录日志创建失败: {e}')
log.error(f'登录日志创建失败: {e}')

@staticmethod
async def delete(*, pk: list[int]) -> int:
Expand Down
58 changes: 32 additions & 26 deletions backend/common/exception/exception_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from uvicorn.protocols.http.h11_impl import STATUS_PHRASES

from backend.common.exception.errors import BaseExceptionMixin
from backend.common.log import log
from backend.common.response.response_code import CustomResponseCode, StandardResponseCode
from backend.common.response.response_schema import response_base
from backend.common.schema import (
Expand Down Expand Up @@ -78,9 +77,9 @@ async def _validation_exception_handler(request: Request, e: RequestValidationEr
'code': StandardResponseCode.HTTP_422,
'msg': msg,
'data': data,
'trace_id': get_request_trace_id(request),
}
request.state.__request_validation_exception__ = content # 用于在中间件中获取异常信息
content.update(trace_id=get_request_trace_id(request))
return MsgSpecJSONResponse(status_code=422, content=content)


Expand All @@ -103,10 +102,11 @@ async def http_exception_handler(request: Request, exc: HTTPException):
else:
res = response_base.fail(res=CustomResponseCode.HTTP_400)
content = res.model_dump()
request.state.__request_http_exception__ = content # 用于在中间件中获取异常信息
request.state.__request_http_exception__ = content
content.update(trace_id=get_request_trace_id(request))
return MsgSpecJSONResponse(
status_code=_get_exception_code(exc.status_code),
content=content.update(trace_id=get_request_trace_id(request)),
content=content,
headers=exc.headers,
)

Expand Down Expand Up @@ -141,14 +141,16 @@ async def pydantic_user_error_handler(request: Request, exc: PydanticUserError):
:param exc:
:return:
"""
content = {
'code': StandardResponseCode.HTTP_500,
'msg': CUSTOM_USAGE_ERROR_MESSAGES.get(exc.code),
'data': None,
}
request.state.__request_pydantic_user_error__ = content
content.update(trace_id=get_request_trace_id(request))
return MsgSpecJSONResponse(
status_code=StandardResponseCode.HTTP_500,
content={
'code': StandardResponseCode.HTTP_500,
'msg': CUSTOM_USAGE_ERROR_MESSAGES.get(exc.code),
'data': None,
'trace_id': get_request_trace_id(request),
},
content=content,
)

@app.exception_handler(AssertionError)
Expand All @@ -169,44 +171,44 @@ async def assertion_error_handler(request: Request, exc: AssertionError):
else:
res = response_base.fail(res=CustomResponseCode.HTTP_500)
content = res.model_dump()
request.state.__request_assertion_error__ = content
content.update(trace_id=get_request_trace_id(request))
return MsgSpecJSONResponse(
status_code=StandardResponseCode.HTTP_500,
content=content.update(trace_id=get_request_trace_id(request)),
content=content,
)

@app.exception_handler(BaseExceptionMixin)
async def custom_exception_handler(request: Request, exc: BaseExceptionMixin):
"""
全局异常处理
全局自定义异常处理
:param request:
:param exc:
:return:
"""
content = {
'code': exc.code,
'msg': str(exc.msg),
'data': exc.data if exc.data else None,
}
request.state.__request_custom_exception__ = content
content.update(trace_id=get_request_trace_id(request))
return MsgSpecJSONResponse(
status_code=_get_exception_code(exc.code),
content={
'code': exc.code,
'msg': str(exc.msg),
'data': exc.data if exc.data else None,
'trace_id': get_request_trace_id(request),
},
content=content,
background=exc.background,
)

@app.exception_handler(Exception)
async def all_exception_handler(request: Request, exc: Exception):
async def all_unknown_exception_handler(request: Request, exc: Exception):
"""
全局异常处理
全局未知异常处理
:param request:
:param exc:
:return:
"""
import traceback

log.error(f'未知异常: {exc}')
log.error(traceback.format_exc())
if settings.ENVIRONMENT == 'dev':
content = {
'code': StandardResponseCode.HTTP_500,
Expand All @@ -216,9 +218,11 @@ async def all_exception_handler(request: Request, exc: Exception):
else:
res = response_base.fail(res=CustomResponseCode.HTTP_500)
content = res.model_dump()
request.state.__request_all_unknown_exception__ = content
content.update(trace_id=get_request_trace_id(request))
return MsgSpecJSONResponse(
status_code=StandardResponseCode.HTTP_500,
content=content.update(trace_id=get_request_trace_id(request)),
content=content,
)

if settings.MIDDLEWARE_CORS:
Expand Down Expand Up @@ -251,9 +255,11 @@ async def cors_custom_code_500_exception_handler(request, exc):
else:
res = response_base.fail(res=CustomResponseCode.HTTP_500)
content = res.model_dump()
request.state.__request_cors_500_exception__ = content
content.update(trace_id=get_request_trace_id(request))
response = MsgSpecJSONResponse(
status_code=exc.code if isinstance(exc, BaseExceptionMixin) else StandardResponseCode.HTTP_500,
content=content.update(trace_id=get_request_trace_id(request)),
content=content,
background=exc.background if isinstance(exc, BaseExceptionMixin) else None,
)
origin = request.headers.get('origin')
Expand Down
46 changes: 24 additions & 22 deletions backend/middleware/opera_log_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async def dispatch(self, request: Request, call_next) -> Response:

# 执行请求
start_time = timezone.now()
res = await self.execute_request(request, call_next)
request_next = await self.execute_request(request, call_next)
end_time = timezone.now()
cost_time = (end_time - start_time).total_seconds() * 1000.0

Expand All @@ -77,20 +77,20 @@ async def dispatch(self, request: Request, call_next) -> Response:
browser=request.state.browser,
device=request.state.device,
args=args,
status=res.status,
code=res.code,
msg=res.msg,
status=request_next.status,
code=request_next.code,
msg=request_next.msg,
cost_time=cost_time,
opera_time=start_time,
)
create_task(OperaLogService.create(obj_in=opera_log_in)) # noqa: ignore

# 错误抛出
err = res.err
err = request_next.err
if err:
raise err from None

return res.response
return request_next.response

async def execute_request(self, request: Request, call_next) -> RequestCallNext:
"""执行请求"""
Expand All @@ -101,7 +101,7 @@ async def execute_request(self, request: Request, call_next) -> RequestCallNext:
response = None
try:
response = await call_next(request)
code, msg = self.validation_exception_handler(request, code, msg)
code, msg = self.request_exception_handler(request, code, msg)
except Exception as e:
log.error(f'请求异常: {e}')
# code 处理包含 SQLAlchemy 和 Pydantic
Expand All @@ -113,22 +113,24 @@ async def execute_request(self, request: Request, call_next) -> RequestCallNext:
return RequestCallNext(code=str(code), msg=msg, status=status, err=err, response=response)

@staticmethod
def validation_exception_handler(request: Request, code: int, msg: str) -> tuple[str, str]:
def request_exception_handler(request: Request, code: int, msg: str) -> tuple[str, str]:
"""请求异常处理器"""
try:
http_exception = request.state.__request_http_exception__
except AttributeError:
pass
else:
code = http_exception.get('code', 500)
msg = http_exception.get('msg', 'Internal Server Error')
try:
validation_exception = request.state.__request_validation_exception__
except AttributeError:
pass
else:
code = validation_exception.get('code', 400)
msg = validation_exception.get('msg', 'Bad Request')
exception_states = [
'__request_http_exception__',
'__request_validation_exception__',
'__request_pydantic_user_error__',
'__request_assertion_error__',
'__request_custom_exception__',
'__request_all_unknown_exception__',
'__request_cors_500_exception__',
]
for state in exception_states:
exception = getattr(request.state, state, None)
if exception:
code = exception.get('code')
msg = exception.get('msg')
break
log.error(f'请求异常: {msg}')
return code, msg

@staticmethod
Expand Down

0 comments on commit 4a9119c

Please sign in to comment.