asynchronous - 多级异步代码中的 Dart 错误

标签 asynchronous dart

考虑以下代码

import 'dart:async';

Future main() async {
  try {
    print("trying");
    await doSomething();
    print("success");
  } catch (e) {
    print("caught");
  }
}

Future<int> doSomething() async {
  await doSomethingElse();
  return 5;
}

Future<int> doSomethingElse() async {
  throw new Exception();
}

运行时,抛出异常doSomethingElse()被追上 main() ,一切都按预期工作。但是,请说写 doSomething() 的人方法没有意识到doSomethingElse()是异步的,而是写了以下内容(注意缺少的 await )。

Future<int> doSomething() async {
  doSomethingElse();
  return 5;
}

现在根本没有捕获异常。相反,输出现在看起来像这样:

trying
success
Unhandled exception:
Uncaught Error: Exception
Stack Trace:
#0      doSomethingElse.<doSomethingElse_async_body> (file:///C:/code/test.dart:19:7)
#1      Future.Future.<anonymous closure> (dart:async/future.dart:118)
<snip>

发生的事情是doSomething()立即返回,然后稍后返回,在另一个上下文中,doSomethingElse()正在抛出错误,立即停止所有执行。我知道对此的回答可能是“好吧,那就不要那样做。”但我正在考虑可能无法控制我正在调用的方法的情况(比如它们是否是库的一部分)。

这种情况导致了几个相关的问题:
  • 作为main()的作者, 有什么办法可以确定我给 doSomething() 的电话不会以未处理的异常结束?还是我依赖​​于 doSomething() 的作者确保所有可能的异常都被处理或传播到返回的 future ?有没有办法附加某种全局错误处理程序,可以从废弃的 future 中捕获错误?
  • 作为doSomething()的作者, 如果我不想等 doSomethingElse() (例如,它写入日志,所以我既不需要输出也不需要担心处理错误)。我能做些什么来防止 doSomethingElse() 中的错误除了将程序的每次调用都包装为 try/catch 块(这可能很麻烦且容易被忽视)之外,是否停止程序?
  • 作为doSomethingElse()的作者,是否有一些我可以使用的模式允许我以等待 Future 完成的调用者可以自己处理该异常的方式抛出异常,而不等待 Future 的调用者不必担心捕获异常(exception)?在这方面我最好的想法是返回一个特殊对象而不是抛出异常,但这会增加很多额外的麻烦并使该方法更难使用。

  • 注意:我在这里使用 async/await 语法,但这个问题应该与更严格的基于 Future 的构造同样相关(你在 doSomething() 中返回一个新的 Future,而不是 .then() 来自 doSomethingElse()

    最佳答案

    未捕获的异步错误被处理到当前区域的错误处理程序。
    您看到的是根区域的错误处理程序将错误报告为未捕获,这也会终止隔离。

    你想要的是为你的代码引入一个不同的错误处理程序,通过运行它 runZoned带有错误处理程序:

    import "dart:async";
    main() {
      runZoned(() async {
        try {
          print("trying");
          await doSomething();
          print("success");
        } catch (e) {
          print("caught");
        }
      }, onError: (e, s) {
        print("uncaught");
      });
    }
    

    关于asynchronous - 多级异步代码中的 Dart 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27791631/

    相关文章:

    firebase - Flutter Firestore甚至在提供orderby函数后仍以错误的顺序获取

    dart - 如何在flutter中返回一个项目和项目列表

    html - Dart如何创建模式页面?

    node.js - 如何同步向mongo插入数据(Nodejs、Express)

    javascript - AngularJS REST 资源 - 刷新查询

    c# - 取消异步检索 URL 的任务

    ios - 如何在异步调用中退出循环?

    Perl AnyEvent::HTTP 请求使用代理失败

    webview - Flutter WebviewPlugin 去除网站的页眉和页脚

    dart - 从任意文件导入类