@@ -93,12 +93,12 @@ def register_middleware(self, middleware: Type[Middleware]):
9393 """注册一个中间件"""
9494 name = middleware .get_name ()
9595 if name in self ._middlewares :
96- logger .opt (colors = True ).debug (
96+ logger .opt (colors = True ).warning (
9797 f'Middleware "<y>{ escape_tag (name )} </y>" already exists'
9898 )
9999 return
100100 self ._middlewares [name ] = middleware
101- logger .opt (colors = True ).debug (
101+ logger .opt (colors = True ).info (
102102 f'Succeeded to load middleware "<y>{ escape_tag (name )} </y>"'
103103 )
104104
@@ -121,8 +121,6 @@ async def _call_api(self, middleware: Middleware, api: str, **kwargs: Any) -> An
121121 "data" : e .data ,
122122 "message" : e .message ,
123123 }
124- except Exception as e :
125- logger .debug (e )
126124
127125 async def get_latest_events (
128126 self ,
@@ -217,17 +215,13 @@ async def _ws_send(
217215 event = await queue .get ()
218216 await websocket .send (encode_data (event .dict (), conn .use_msgpack ))
219217 except WebSocketClosed as e :
220- logger .opt (colors = True , exception = e ).log (
221- "WARNING" ,
222- "<y><bg #f8bbd0>WebSocket Closed</bg #f8bbd0></y>" ,
223- e ,
218+ logger .opt (colors = True ).warning (
219+ "<y><bg #f8bbd0>WebSocket Closed</bg #f8bbd0></y>"
224220 )
225221 except Exception as e :
226- logger .opt (colors = True , exception = e ).log (
227- "ERROR" ,
222+ logger .opt (colors = True ).exception (
228223 "<r><bg #f8bbd0>Error while process data from websocket"
229- ". Trying to reconnect...</bg #f8bbd0></r>" ,
230- e ,
224+ ". Trying to reconnect...</bg #f8bbd0></r>"
231225 )
232226 finally :
233227 middleware .queues .remove (queue )
@@ -236,28 +230,43 @@ async def _ws_recv(self, middleware: Middleware, websocket: WebSocket) -> None:
236230 try :
237231 while True :
238232 raw_data = await websocket .receive ()
239- data = (
240- json .loads (raw_data )
241- if isinstance (raw_data , str )
242- else msgpack .unpackb (raw_data )
243- )
244- resp = await self ._call_api (
245- middleware , data ["action" ], ** data ["params" ]
246- )
247- if "echo" in data :
248- resp ["echo" ] = data ["echo" ]
233+ try :
234+ data = (
235+ json .loads (raw_data )
236+ if isinstance (raw_data , str )
237+ else msgpack .unpackb (raw_data )
238+ )
239+ resp = await self ._call_api (
240+ middleware , data ["action" ], ** data ["params" ]
241+ )
242+ if "echo" in data :
243+ resp ["echo" ] = data ["echo" ]
244+ # 格式错误(包括实现不支持 MessagePack 的情况)、必要字段缺失或字段类型错误
245+ except (json .JSONDecodeError , msgpack .UnpackException ):
246+ resp = {
247+ "status" : "failed" ,
248+ "retcode" : 10001 ,
249+ "data" : None ,
250+ "message" : "Invalid data format" ,
251+ }
252+ # OneBot 实现内部发生了未捕获的意料之外的异常
253+ except Exception as e :
254+ resp = {
255+ "status" : "failed" ,
256+ "retcode" : 20002 ,
257+ "data" : None ,
258+ "message" : str (e ),
259+ }
249260 await websocket .send (encode_data (resp , isinstance (raw_data , str )))
250261 except WebSocketClosed as e :
251- logger .opt (colors = True , exception = e ).log (
252- "WARNING" ,
253- f"WebSocket for Bot { escape_tag (middleware .self_id )} closed by peer" ,
262+ logger .opt (colors = True ).warning (
263+ f"WebSocket for Bot { escape_tag (middleware .self_id )} closed by peer"
254264 )
265+ # 与 WebSocket 服务器的连接发生了意料之外的错误
255266 except Exception as e :
256- logger .opt (colors = True , exception = e ).log (
257- "ERROR" ,
267+ logger .opt (colors = True ).exception (
258268 "<r><bg #f8bbd0>Error while process data from websocket "
259- f"for bot { escape_tag (middleware .self_id )} .</bg #f8bbd0></r>" ,
260- e ,
269+ f"for bot { escape_tag (middleware .self_id )} .</bg #f8bbd0></r>"
261270 )
262271
263272 async def _handle_http (
@@ -269,32 +278,47 @@ async def _handle_http(
269278 ) -> Response :
270279 if response := self ._check_access_token (request , conn .access_token ):
271280 return response
281+
282+ # 如果收到不支持的 Content-Type 请求头,必须返回 HTTP 状态码 415 Unsupported Media Type
283+ content_type = request .headers .get ("Content-Type" )
284+ if content_type not in ("application/json" , "application/msgpack" ):
285+ return Response (415 , content = "Invalid Content-Type" )
286+
272287 try :
273- if request .content :
274- if (
275- content_type := request . headers . get ( "Content-Type" )
276- ) == "application/ msgpack" :
277- data = msgpack . unpackb ( request . content )
278- elif content_type == "application/ json" :
279- data = json . loads ( request . content )
280- else :
281- return Response ( 415 , content = "Invalid Content-Type" )
282- resp = await self . _call_api (
283- middleware ,
284- data ["action " ],
285- queue = queue ,
286- ** data [ "params" ],
287- )
288- if "echo" in data :
289- resp [ "echo" ] = data [ "echo" ]
290- return Response (
291- 200 ,
292- headers = { "Content-Type " : content_type } ,
293- content = encode_data ( resp , content_type != "application/json" ) ,
294- )
288+ if request .content is None :
289+ raise ValueError ( "Empty request body" )
290+ if content_type == "application/msgpack" :
291+ data = msgpack . unpackb ( request . content )
292+ else :
293+ data = json . loads ( request . content )
294+
295+ resp = await self . _call_api (
296+ middleware ,
297+ data [ "action" ],
298+ queue = queue ,
299+ ** data ["params " ],
300+ )
301+ if "echo" in data :
302+ resp [ "echo" ] = data [ "echo" ]
303+ except ( json . JSONDecodeError , msgpack . UnpackException , ValueError ) :
304+ resp = {
305+ "status" : "failed" ,
306+ "retcode" : 10001 ,
307+ "data " : None ,
308+ "message" : "Invalid data format" ,
309+ }
295310 except Exception as e :
296- logger .debug (e )
297- return Response (204 )
311+ resp = {
312+ "status" : "failed" ,
313+ "retcode" : 20002 ,
314+ "data" : None ,
315+ "message" : str (e ),
316+ }
317+ return Response (
318+ 200 ,
319+ headers = {"Content-Type" : content_type },
320+ content = encode_data (resp , content_type != "application/json" ),
321+ )
298322
299323 async def _handle_ws (
300324 self , middleware : Middleware , conn : WebsocketConfig , websocket : WebSocket
@@ -382,20 +406,33 @@ async def _http_webhook(self, middleware: Middleware, conn: HTTPWebhookConfig):
382406 )
383407 resp = await self .request (request )
384408 if resp .status_code == 200 :
385- if resp .content :
386- if resp .headers .get ("Content-Type" ) == "application/msgpack" :
409+ try :
410+ if resp .content is None :
411+ raise ValueError ("Empty response body" )
412+ if (
413+ content_type := resp .headers .get ("Content-Type" )
414+ ) == "application/msgpack" :
387415 data = msgpack .unpackb (resp .content )
388- elif resp . headers . get ( "Content-Type" ) == "application/json" :
416+ elif content_type == "application/json" :
389417 data = json .loads (resp .content )
390418 else :
391- logger .exception ("Invalid Content-Type" )
419+ logger .error ("Invalid Content-Type" )
392420 continue
393421 for action in data :
394422 await self ._call_api (
395423 middleware , action ["action" ], ** action ["params" ]
396424 )
397- except Exception as e :
398- logger .debug (e )
425+ # 动作请求执行出错
426+ except Exception :
427+ logger .exception ("HTTP Webhook Response action failed" )
428+ # 事件推送成功,并不做更多处理
429+ elif resp .status_code == 204 :
430+ pass
431+ # 事件推送失败
432+ else :
433+ logger .error (f"HTTP Webhook event push failed: { resp } " )
434+ except Exception :
435+ logger .exception ("HTTP Webhook event push failed" )
399436
400437 async def _websocket_rev (
401438 self , middleware : Middleware , conn : WebsocketReverseConfig
@@ -434,24 +471,18 @@ async def _websocket_rev(
434471 await t2
435472 t1 .cancel ()
436473 except WebSocketClosed as e :
437- logger .opt (colors = True , exception = e ).log (
438- "WARNING" ,
439- "<y><bg #f8bbd0>WebSocket Closed</bg #f8bbd0></y>" ,
440- e ,
474+ logger .opt (colors = True ).warning (
475+ "<y><bg #f8bbd0>WebSocket Closed</bg #f8bbd0></y>"
441476 )
442477 except Exception as e :
443- logger .opt (colors = True , exception = e ).log (
444- "ERROR" ,
478+ logger .opt (colors = True ).exception (
445479 "<r><bg #f8bbd0>Error while process data from websocket"
446480 f"{ escape_tag (str (conn .url ))} . Trying to reconnect...</bg #f8bbd0></r>" ,
447- e ,
448481 )
449482 except Exception as e :
450- logger .opt (colors = True ).log (
451- "WARNING" ,
483+ logger .opt (colors = True ).warning (
452484 "<y><bg #f8bbd0>Error while setup websocket to "
453485 f"{ escape_tag (str (conn .url ))} . Trying to reconnect...</bg #f8bbd0></y>" ,
454- e ,
455486 )
456487 await asyncio .sleep (conn .reconnect_interval )
457488
@@ -473,9 +504,9 @@ def import_middlewares(self, middlewares: Optional[Set[str]] = None):
473504 )
474505 self .register_middleware (getattr (module , "Middleware" ))
475506 else :
476- logger .warning (f"Can not find middleware for Adapter { middleware } " )
477- except Exception as e :
478- logger .warning (f"Can not load middleware for Adapter { middleware } : { e } " )
507+ logger .error (f"Can not find middleware for Adapter { middleware } " )
508+ except Exception :
509+ logger .exception (f"Can not load middleware for Adapter { middleware } :" )
479510
480511 def setup (self ):
481512 @self .driver .on_startup
0 commit comments