From 115b6f0b3070f81e4ca591ab2ff83e2e6b15ca29 Mon Sep 17 00:00:00 2001 From: Wu Clan Date: Tue, 20 Feb 2024 10:40:21 +0800 Subject: [PATCH] Update the response status code in exception handlers (#292) --- .../app/common/exception/exception_handler.py | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/backend/app/common/exception/exception_handler.py b/backend/app/common/exception/exception_handler.py index 60444e73..bcc0ac2f 100644 --- a/backend/app/common/exception/exception_handler.py +++ b/backend/app/common/exception/exception_handler.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +from asgiref.sync import sync_to_async from fastapi import FastAPI, Request from fastapi.exceptions import RequestValidationError from pydantic import ValidationError from pydantic.errors import PydanticUserError from starlette.exceptions import HTTPException from starlette.middleware.cors import CORSMiddleware +from uvicorn.protocols.http.h11_impl import STATUS_PHRASES from backend.app.common.exception.errors import BaseExceptionMixin from backend.app.common.log import log @@ -19,6 +21,28 @@ from backend.app.schemas.base import ( from backend.app.utils.serializers import MsgSpecJSONResponse +@sync_to_async +def _get_exception_code(status_code: int): + """ + 获取返回状态码, OpenAPI, Uvicorn... 可用状态码基于 RFC 定义, 详细代码见下方链接 + + `python 状态码标准支持 `__ + + `IANA 状态码注册表 `__ + + :param status_code: + :return: + """ + try: + STATUS_PHRASES[status_code] + except Exception: # noqa: ignore + code = StandardResponseCode.HTTP_400 + else: + code = status_code + return code + + async def _validation_exception_handler(request: Request, e: RequestValidationError | ValidationError): """ 数据验证异常处理 @@ -48,7 +72,7 @@ async def _validation_exception_handler(request: Request, e: RequestValidationEr error_input = error.get('input') field = str(error.get('loc')[-1]) error_msg = error.get('msg') - message = f'{field} {error_msg},输入:{error_input}' + message = f'{error_msg}{field},输入:{error_input}' if settings.ENVIRONMENT == 'dev' else error_msg msg = f'请求参数非法: {message}' data = {'errors': errors} if settings.ENVIRONMENT == 'dev' else None content = { @@ -81,7 +105,7 @@ def register_exception(app: FastAPI): content = res.model_dump() request.state.__request_http_exception__ = content # 用于在中间件中获取异常信息 return MsgSpecJSONResponse( - status_code=StandardResponseCode.HTTP_400, + status_code=await _get_exception_code(exc.status_code), content=content, headers=exc.headers, ) @@ -160,7 +184,7 @@ def register_exception(app: FastAPI): """ if isinstance(exc, BaseExceptionMixin): return MsgSpecJSONResponse( - status_code=StandardResponseCode.HTTP_400, + status_code=await _get_exception_code(exc.code), content={ 'code': exc.code, 'msg': str(exc.msg), @@ -175,7 +199,7 @@ def register_exception(app: FastAPI): log.error(traceback.format_exc()) if settings.ENVIRONMENT == 'dev': content = { - 'code': 500, + 'code': StandardResponseCode.HTTP_500, 'msg': str(exc), 'data': None, }