继承TeamsActivityHandler时onTurnError未被调用的正确使用方法咨询
问题根因
com.microsoft.bot:bot-integration-core 4.14版本中,TeamsActivityHandler 对所有invoke类型的活动(包括自适应卡片点击、按钮触发的调用请求等)做了内置异常捕获,所有你重写的onAdaptiveCardInvoke、onTeamsCardActionInvoke等invoke相关方法抛出的异常,都会被框架内部吞掉,不会冒泡到BotFrameworkAdapter的onTurnError处理器,这是框架该版本的固有设计。
可行解决方案
方案1:重写invoke入口方法,向上抛出异常(最推荐)
TeamsActivityHandler 处理invoke请求的入口是onInvokeActivity方法,你可以重写该方法,添加异常透传逻辑,让异常可以冒泡到上层的onTurnError处理器:
@Override protected CompletableFuture<InvokeResponse> onInvokeActivity(TurnContext turnContext) { return super.onInvokeActivity(turnContext) // 捕获invoke链路抛出的所有异常 .exceptionally(throwable -> { // 方式1:直接将异常重新抛出,会自动触发adapter的onTurnError throw new CompletionException(throwable.getCause()); // 方式2:如果不想直接抛出,也可以在这里手动调用你在onTurnError中定义的公共错误处理逻辑 // yourCustomErrorHandler(turnContext, throwable.getCause()); // 同时可以构造合规的InvokeResponse返回给Teams客户端,避免用户侧无报错提示 // return new InvokeResponse(500, "服务内部错误"); }); }
方案2:所有invoke相关方法内置异常捕获
在每个你重写的invoke类方法(onAdaptiveCardInvoke、onTeams*相关invoke方法)内部添加try-catch逻辑,捕获到异常后统一调用你定义的全局错误处理逻辑,保持和onTurnError的处理逻辑一致即可。该方案需要每个方法单独处理,容易遗漏,适合仅少量重写invoke方法的场景。
方案3:切换继承父类
如果你没有用到TeamsActivityHandler提供的专属Teams扩展能力(比如团队成员变更事件、Teams会话专属事件处理等),可以直接继承父类ActivityHandler,该类没有内置invoke异常捕获逻辑,所有场景抛出的异常都会正常触发onTurnError。
注意事项
如果选择手动透传异常,建议在onTurnError中补充invoke请求的响应逻辑,构造符合规范的InvokeResponse返回,否则Teams客户端可能会显示「操作失败」之类的通用报错,影响用户体验。
内容的提问来源于stack exchange,提问作者mazdack

