9
9
from starlette .exceptions import HTTPException
10
10
from starlette .middleware .cors import CORSMiddleware
11
11
from starlette .responses import JSONResponse
12
- from uvicorn .protocols .http .h11_impl import STATUS_PHRASES
13
12
14
13
from backend .app .common .exception .errors import BaseExceptionMixin
15
14
from backend .app .common .log import log
16
- from backend .app .common .response .response_schema import response_base
15
+ from backend .app .common .response .response_code import StandardResponseCode , CustomResponseCode
16
+ from backend .app .common .response .response_schema import response_base , ResponseModel
17
17
from backend .app .core .conf import settings
18
18
19
19
20
- def _get_exception_code (status_code ):
21
- """
22
- 获取返回状态码, OpenAPI, Uvicorn... 可用状态码基于 RFC 定义, 详细代码见下方链接
23
-
24
- `python 状态码标准支持 <https://github.com/python/cpython/blob/6e3cc72afeaee2532b4327776501eb8234ac787b/Lib/http
25
- /__init__.py#L7>`__
26
-
27
- `IANA 状态码注册表 <https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>`__
28
-
29
- :param status_code:
30
- :return:
31
- """
32
- try :
33
- STATUS_PHRASES [status_code ]
34
- except Exception :
35
- code = 400
36
- else :
37
- code = status_code
38
- return code
39
-
40
-
41
20
def register_exception (app : FastAPI ):
42
21
@app .exception_handler (HTTPException )
43
22
async def http_exception_handler (request : Request , exc : HTTPException ):
@@ -48,11 +27,11 @@ async def http_exception_handler(request: Request, exc: HTTPException):
48
27
:param exc:
49
28
:return:
50
29
"""
51
- content = { ' code' : exc .status_code , ' msg' : exc .detail }
30
+ content = ResponseModel ( code = exc .status_code , msg = exc .detail ). dict ()
52
31
request .state .__request_http_exception__ = content # 用于在中间件中获取异常信息
53
32
return JSONResponse (
54
- status_code = _get_exception_code ( exc . status_code ) ,
55
- content = await response_base .fail (** content ),
33
+ status_code = StandardResponseCode . HTTP_400 ,
34
+ content = content if settings . ENVIRONMENT == 'dev' else await response_base .fail (CustomResponseCode . HTTP_400 ),
56
35
headers = exc .headers ,
57
36
)
58
37
@@ -94,13 +73,16 @@ async def validation_exception_handler(request: Request, exc: RequestValidationE
94
73
message += f'{ data .get (field , field ) if field != "__root__" else "" } { msg } ' + '.'
95
74
elif isinstance (raw_error .exc , json .JSONDecodeError ):
96
75
message += 'json解析失败'
97
- content = {
98
- ' code' : 422 ,
99
- ' msg' : '请求参数非法' if len (message ) == 0 else f'请求参数非法: { message } ' ,
100
- ' data' : {'errors' : exc .errors ()} if message == '' and settings . UVICORN_RELOAD is True else None ,
101
- }
76
+ content = ResponseModel (
77
+ code = StandardResponseCode . HTTP_422 ,
78
+ msg = '请求参数非法' if len (message ) == 0 else f'请求参数非法: { message } ' ,
79
+ data = {'errors' : exc .errors ()} if message == '' else None ,
80
+ ). dict ()
102
81
request .state .__request_validation_exception__ = content # 用于在中间件中获取异常信息
103
- return JSONResponse (status_code = 422 , content = await response_base .fail (** content ))
82
+ return JSONResponse (
83
+ status_code = StandardResponseCode .HTTP_422 ,
84
+ content = content if settings .ENVIRONMENT == 'dev' else await response_base .fail (CustomResponseCode .HTTP_422 ),
85
+ )
104
86
105
87
@app .exception_handler (Exception )
106
88
async def all_exception_handler (request : Request , exc : Exception ):
@@ -113,24 +95,28 @@ async def all_exception_handler(request: Request, exc: Exception):
113
95
"""
114
96
if isinstance (exc , BaseExceptionMixin ):
115
97
return JSONResponse (
116
- status_code = _get_exception_code (exc .code ),
117
- content = await response_base .fail (code = exc .code , msg = str (exc .msg ), data = exc .data if exc .data else None ),
98
+ status_code = StandardResponseCode .HTTP_400 ,
99
+ content = ResponseModel (
100
+ code = exc .code ,
101
+ msg = str (exc .msg ),
102
+ data = exc .data if exc .data else None ,
103
+ ).dict (),
118
104
background = exc .background ,
119
105
)
120
106
121
107
elif isinstance (exc , AssertionError ):
122
108
return JSONResponse (
123
- status_code = 500 ,
124
- content = await response_base . fail (
125
- code = 500 ,
109
+ status_code = StandardResponseCode . HTTP_500 ,
110
+ content = ResponseModel (
111
+ code = StandardResponseCode . HTTP_500 ,
126
112
msg = ',' .join (exc .args )
127
113
if exc .args
128
114
else exc .__repr__ ()
129
115
if not exc .__repr__ ().startswith ('AssertionError()' )
130
116
else exc .__doc__ ,
131
- )
117
+ ). dict ()
132
118
if settings .ENVIRONMENT == 'dev'
133
- else await response_base .fail (code = 500 , msg = 'Internal Server Error' ),
119
+ else await response_base .fail (CustomResponseCode . HTTP_500 ),
134
120
)
135
121
136
122
else :
@@ -139,15 +125,15 @@ async def all_exception_handler(request: Request, exc: Exception):
139
125
log .error (f'未知异常: { exc } ' )
140
126
log .error (traceback .format_exc ())
141
127
return JSONResponse (
142
- status_code = 500 ,
143
- content = await response_base . fail (code = 500 , msg = str (exc ))
128
+ status_code = StandardResponseCode . HTTP_500 ,
129
+ content = ResponseModel (code = 500 , msg = str (exc )). dict ( )
144
130
if settings .ENVIRONMENT == 'dev'
145
- else await response_base .fail (code = 500 , msg = 'Internal Server Error' ),
131
+ else await response_base .fail (StandardResponseCode . HTTP_500 ),
146
132
)
147
133
148
134
if settings .MIDDLEWARE_CORS :
149
135
150
- @app .exception_handler (500 )
136
+ @app .exception_handler (StandardResponseCode . HTTP_500 )
151
137
async def cors_status_code_500_exception_handler (request , exc ):
152
138
"""
153
139
跨域 500 异常处理
@@ -159,12 +145,12 @@ async def cors_status_code_500_exception_handler(request, exc):
159
145
:return:
160
146
"""
161
147
response = JSONResponse (
162
- status_code = exc .code if isinstance (exc , BaseExceptionMixin ) else 500 ,
163
- content = { ' code' : exc .code , ' msg' : exc .msg , ' data' : exc .data }
148
+ status_code = exc .code if isinstance (exc , BaseExceptionMixin ) else StandardResponseCode . HTTP_500 ,
149
+ content = ResponseModel ( code = exc .code , msg = exc .msg , data = exc .data ). dict ()
164
150
if isinstance (exc , BaseExceptionMixin )
165
- else await response_base . fail (code = 500 , msg = str (exc ))
151
+ else ResponseModel (code = StandardResponseCode . HTTP_500 , msg = str (exc )). dict ( )
166
152
if settings .ENVIRONMENT == 'dev'
167
- else await response_base .fail (code = 500 , msg = 'Internal Server Error' ),
153
+ else await response_base .fail (CustomResponseCode . HTTP_500 ),
168
154
background = exc .background if isinstance (exc , BaseExceptionMixin ) else None ,
169
155
)
170
156
origin = request .headers .get ('origin' )
0 commit comments