构建

调用并接住 — 拒绝不是异常

作者: makemind · 2026年4月3日

第二篇知道了有什么。现在去调。

结果不是一个值

final ok = await client.callTool('desk.admit', {'count': 1});

回来的不是数字,而是 一份内容列表。可能是文本,可能是图片,也可能有好几项。所以把取值这件事收在一处。

Map<String, dynamic> decode(CallToolResult r) {
  final first = r.content.first;
  if (first is! TextContent) {
    throw StateError('expected text content, got ${first.runtimeType}');
  }
  return jsonDecode(first.text) as Map<String, dynamic>;
}

去掉 is! TextContent 直接强转,等哪天服务端混进一张图片,它会在 完全不相干的地方 炸。在这里拦住,栈才读得懂。

admit 1 -> {waiting: 2}

拒绝不会以 throw 到来

调一下服务端第三篇里做的那个拒绝。

final refused = await client.callTool('desk.admit', {'count': 99});
final text = (refused.content.first as TextContent).text;
stdout.writeln('admit 99 -> isError=${refused.isError} "$text"');
admit 99 -> isError=true "only 2 waiting"

没有抛异常。 await 正常完成,结果上带着 isError: true,理由在文本里。

不知道这一点,就会写成:

try {
  await client.callTool('desk.admit', {'count': 99});
  // 走到这儿了,说明成功
} catch (e) {
  // 以为拒绝会掉到这里……其实不会
}

拒绝进不了 catch,于是 被当成成功处理。 屏上写着「放进 99 人」,而服务端一个人也没放。

此内容需要开发者或更高等级

登录并升级您的方案即可继续阅读。

查看方案
Twitter