diff --git a/libraries/botbuilder-core/botbuilder/core/adapters/test_adapter.py b/libraries/botbuilder-core/botbuilder/core/adapters/test_adapter.py index ebfeb303a..05201ecc0 100644 --- a/libraries/botbuilder-core/botbuilder/core/adapters/test_adapter.py +++ b/libraries/botbuilder-core/botbuilder/core/adapters/test_adapter.py @@ -699,6 +699,7 @@ async def wait_for_activity(): reply = adapter.activity_buffer.pop(0) raise RuntimeError( f"TestAdapter.assert_no_reply(): '{reply.text}' is responded when waiting for no reply." + f"(Activity type: {reply.type})" ) await asyncio.sleep(0.05) diff --git a/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py b/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py index 557fd56a2..c74f81f8d 100644 --- a/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py +++ b/libraries/botbuilder-core/botbuilder/core/show_typing_middleware.py @@ -93,12 +93,10 @@ def stop_interval(): ): start_interval(context, self._delay, self._period) - # call the bot logic - result = await logic() - - stop_interval() - - return result + try: + return await logic() + finally: + stop_interval() @staticmethod def _is_skill_bot(context: TurnContext) -> bool: diff --git a/libraries/botbuilder-core/tests/test_show_typing_middleware.py b/libraries/botbuilder-core/tests/test_show_typing_middleware.py index 9d0e0b7ce..8549954a1 100644 --- a/libraries/botbuilder-core/tests/test_show_typing_middleware.py +++ b/libraries/botbuilder-core/tests/test_show_typing_middleware.py @@ -4,8 +4,8 @@ from uuid import uuid4 import aiounittest -from botbuilder.core import ShowTypingMiddleware, TurnContext -from botbuilder.core.adapters import TestAdapter +from botbuilder.core import Middleware, ShowTypingMiddleware, TurnContext +from botbuilder.core.adapters import TestAdapter, TestFlow from botbuilder.schema import Activity, ActivityTypes from botframework.connector.auth import AuthenticationConstants, ClaimsIdentity @@ -47,6 +47,28 @@ def assert_is_typing(activity, description): # pylint: disable=unused-argument step5 = await step4.assert_reply(assert_is_typing) await step5.assert_reply("echo:bar") + async def test_should_stop_sendind_typing_indicators_when_exception_raised(self): + async def aux(context): + await context.send_activity(f"echo:{context.activity.text}") + raise Exception("test:error") + + class ErrorHandlingMiddleware(Middleware): + async def on_turn(self, context, logic): + try: + await logic() + except Exception as e: + await context.send_activity(f"error:{e.args[0]}") + + adapter = TestAdapter(aux) + + adapter.use(ErrorHandlingMiddleware()) + adapter.use(ShowTypingMiddleware(0.2, 0.4)) + + step1: TestFlow = await adapter.send("foo") + step2 = await step1.assert_reply("echo:foo") + step3 = await step2.assert_reply("error:test:error") + await step3.assert_no_reply("no typing activity should be shown", timeout=450) + async def test_should_not_automatically_send_a_typing_indicator_if_no_middleware( self, ):