|
12 | 12 | AsyncDefaultListenerCompletionHandler, |
13 | 13 | ) |
14 | 14 | from slack_bolt.listener.asyncio_runner import AsyncioListenerRunner |
| 15 | +from slack_bolt.middleware.async_middleware_error_handler import ( |
| 16 | + AsyncCustomMiddlewareErrorHandler, |
| 17 | + AsyncDefaultMiddlewareErrorHandler, |
| 18 | +) |
15 | 19 | from slack_bolt.middleware.message_listener_matches.async_message_listener_matches import ( |
16 | 20 | AsyncMessageListenerMatches, |
17 | 21 | ) |
@@ -334,6 +338,9 @@ async def message_hello(message, say): # async function |
334 | 338 | logger=self._framework_logger, |
335 | 339 | ), |
336 | 340 | ) |
| 341 | + self._async_middleware_error_handler = AsyncDefaultMiddlewareErrorHandler( |
| 342 | + logger=self._framework_logger, |
| 343 | + ) |
337 | 344 |
|
338 | 345 | self._init_middleware_list_done = False |
339 | 346 | self._init_async_middleware_list( |
@@ -499,89 +506,101 @@ async def async_dispatch(self, req: AsyncBoltRequest) -> BoltResponse: |
499 | 506 | async def async_middleware_next(): |
500 | 507 | middleware_state["next_called"] = True |
501 | 508 |
|
502 | | - for middleware in self._async_middleware_list: |
503 | | - middleware_state["next_called"] = False |
504 | | - if self._framework_logger.level <= logging.DEBUG: |
505 | | - self._framework_logger.debug(f"Applying {middleware.name}") |
506 | | - resp = await middleware.async_process( |
507 | | - req=req, resp=resp, next=async_middleware_next |
508 | | - ) |
509 | | - if not middleware_state["next_called"]: |
510 | | - if resp is None: |
511 | | - # next() method was not called without providing the response to return to Slack |
512 | | - # This should not be an intentional handling in usual use cases. |
513 | | - resp = BoltResponse( |
514 | | - status=404, body={"error": "no next() calls in middleware"} |
515 | | - ) |
516 | | - if self._raise_error_for_unhandled_request is True: |
517 | | - await self._async_listener_runner.listener_error_handler.handle( |
518 | | - error=BoltUnhandledRequestError( |
| 509 | + try: |
| 510 | + for middleware in self._async_middleware_list: |
| 511 | + middleware_state["next_called"] = False |
| 512 | + if self._framework_logger.level <= logging.DEBUG: |
| 513 | + self._framework_logger.debug(f"Applying {middleware.name}") |
| 514 | + resp = await middleware.async_process( |
| 515 | + req=req, resp=resp, next=async_middleware_next |
| 516 | + ) |
| 517 | + if not middleware_state["next_called"]: |
| 518 | + if resp is None: |
| 519 | + # next() method was not called without providing the response to return to Slack |
| 520 | + # This should not be an intentional handling in usual use cases. |
| 521 | + resp = BoltResponse( |
| 522 | + status=404, body={"error": "no next() calls in middleware"} |
| 523 | + ) |
| 524 | + if self._raise_error_for_unhandled_request is True: |
| 525 | + await self._async_listener_runner.listener_error_handler.handle( |
| 526 | + error=BoltUnhandledRequestError( |
| 527 | + request=req, |
| 528 | + current_response=resp, |
| 529 | + last_global_middleware_name=middleware.name, |
| 530 | + ), |
519 | 531 | request=req, |
520 | | - current_response=resp, |
521 | | - last_global_middleware_name=middleware.name, |
522 | | - ), |
523 | | - request=req, |
524 | | - response=resp, |
| 532 | + response=resp, |
| 533 | + ) |
| 534 | + return resp |
| 535 | + self._framework_logger.warning( |
| 536 | + warning_unhandled_by_global_middleware(middleware.name, req) |
525 | 537 | ) |
526 | 538 | return resp |
527 | | - self._framework_logger.warning( |
528 | | - warning_unhandled_by_global_middleware(middleware.name, req) |
529 | | - ) |
530 | 539 | return resp |
531 | | - return resp |
532 | 540 |
|
533 | | - for listener in self._async_listeners: |
534 | | - listener_name = get_name_for_callable(listener.ack_function) |
535 | | - self._framework_logger.debug(debug_checking_listener(listener_name)) |
536 | | - if await listener.async_matches(req=req, resp=resp): |
537 | | - # run all the middleware attached to this listener first |
538 | | - ( |
539 | | - middleware_resp, |
540 | | - next_was_not_called, |
541 | | - ) = await listener.run_async_middleware(req=req, resp=resp) |
542 | | - if next_was_not_called: |
| 541 | + for listener in self._async_listeners: |
| 542 | + listener_name = get_name_for_callable(listener.ack_function) |
| 543 | + self._framework_logger.debug(debug_checking_listener(listener_name)) |
| 544 | + if await listener.async_matches(req=req, resp=resp): |
| 545 | + # run all the middleware attached to this listener first |
| 546 | + ( |
| 547 | + middleware_resp, |
| 548 | + next_was_not_called, |
| 549 | + ) = await listener.run_async_middleware(req=req, resp=resp) |
| 550 | + if next_was_not_called: |
| 551 | + if middleware_resp is not None: |
| 552 | + if self._framework_logger.level <= logging.DEBUG: |
| 553 | + debug_message = ( |
| 554 | + debug_return_listener_middleware_response( |
| 555 | + listener_name, |
| 556 | + middleware_resp.status, |
| 557 | + middleware_resp.body, |
| 558 | + starting_time, |
| 559 | + ) |
| 560 | + ) |
| 561 | + self._framework_logger.debug(debug_message) |
| 562 | + return middleware_resp |
| 563 | + # The last listener middleware didn't call next() method. |
| 564 | + # This means the listener is not for this incoming request. |
| 565 | + continue |
| 566 | + |
543 | 567 | if middleware_resp is not None: |
544 | | - if self._framework_logger.level <= logging.DEBUG: |
545 | | - debug_message = debug_return_listener_middleware_response( |
546 | | - listener_name, |
547 | | - middleware_resp.status, |
548 | | - middleware_resp.body, |
549 | | - starting_time, |
550 | | - ) |
551 | | - self._framework_logger.debug(debug_message) |
552 | | - return middleware_resp |
553 | | - # The last listener middleware didn't call next() method. |
554 | | - # This means the listener is not for this incoming request. |
555 | | - continue |
556 | | - |
557 | | - if middleware_resp is not None: |
558 | | - resp = middleware_resp |
559 | | - |
560 | | - self._framework_logger.debug(debug_running_listener(listener_name)) |
561 | | - listener_response: Optional[ |
562 | | - BoltResponse |
563 | | - ] = await self._async_listener_runner.run( |
| 568 | + resp = middleware_resp |
| 569 | + |
| 570 | + self._framework_logger.debug(debug_running_listener(listener_name)) |
| 571 | + listener_response: Optional[ |
| 572 | + BoltResponse |
| 573 | + ] = await self._async_listener_runner.run( |
| 574 | + request=req, |
| 575 | + response=resp, |
| 576 | + listener_name=listener_name, |
| 577 | + listener=listener, |
| 578 | + ) |
| 579 | + if listener_response is not None: |
| 580 | + return listener_response |
| 581 | + |
| 582 | + if resp is None: |
| 583 | + resp = BoltResponse(status=404, body={"error": "unhandled request"}) |
| 584 | + if self._raise_error_for_unhandled_request is True: |
| 585 | + await self._async_listener_runner.listener_error_handler.handle( |
| 586 | + error=BoltUnhandledRequestError( |
| 587 | + request=req, |
| 588 | + current_response=resp, |
| 589 | + ), |
564 | 590 | request=req, |
565 | 591 | response=resp, |
566 | | - listener_name=listener_name, |
567 | | - listener=listener, |
568 | 592 | ) |
569 | | - if listener_response is not None: |
570 | | - return listener_response |
571 | | - |
572 | | - if resp is None: |
573 | | - resp = BoltResponse(status=404, body={"error": "unhandled request"}) |
574 | | - if self._raise_error_for_unhandled_request is True: |
575 | | - await self._async_listener_runner.listener_error_handler.handle( |
576 | | - error=BoltUnhandledRequestError( |
577 | | - request=req, |
578 | | - current_response=resp, |
579 | | - ), |
| 593 | + return resp |
| 594 | + return self._handle_unmatched_requests(req, resp) |
| 595 | + |
| 596 | + except Exception as error: |
| 597 | + resp = BoltResponse(status=500, body="") |
| 598 | + await self._async_middleware_error_handler.handle( |
| 599 | + error=error, |
580 | 600 | request=req, |
581 | 601 | response=resp, |
582 | 602 | ) |
583 | 603 | return resp |
584 | | - return self._handle_unmatched_requests(req, resp) |
585 | 604 |
|
586 | 605 | def _handle_unmatched_requests( |
587 | 606 | self, req: AsyncBoltRequest, resp: BoltResponse |
@@ -729,6 +748,10 @@ async def custom_error_handler(error, body, logger): |
729 | 748 | func=func, |
730 | 749 | ) |
731 | 750 | ) |
| 751 | + self._async_middleware_error_handler = AsyncCustomMiddlewareErrorHandler( |
| 752 | + logger=self._framework_logger, |
| 753 | + func=func, |
| 754 | + ) |
732 | 755 | return func |
733 | 756 |
|
734 | 757 | # ------------------------- |
|
0 commit comments