使用dart与stack_trace链的异步

时间:2015-03-03 23:04:31

标签: dart dart-async

我正在尝试利用stack_trace提供的Chain对象,如下所示:

import 'dart:async';
import 'package:stack_trace/stack_trace.dart';

main() async {
  print('Hello world: ${console_test.calculate()}!');
  Chain.capture(() async {
    try {
      await testFunction();
    } catch(e,st) {
      print(Trace.format(new Chain.forTrace(st)));
    }
  });
}


Future testFunction() async {
  throw new Exception("TEST");
}

我得到的输出是:

Hello world: 42!
main.dart 4:1  main.<async>.<fn>.<async>

我知道输出的堆栈跟踪应该包含testFunction,但由于某种原因它不是。如果我用期货代替它:

import 'dart:async';
import 'package:stack_trace/stack_trace.dart';

main() async {
  print('Hello world: ${console_test.calculate()}!');
  Chain.capture(()  {
      return testFunction();
  }, onError: (e, stackTrace) => print(Trace.format(new Chain.forTrace(stackTrace))));
}

Future testFunction() async {
  throw new Exception("TEST");
}

我获得了更多预期的输出:

Hello world: 42!
main.dart 17:3       testFunction.<async>
dart:async           _Completer.completeError
main.dart 4:1        testFunction.<async>
dart:async           Future.Future
main.dart 4:1        testFunction
main.dart 11:26      main.<async>.<fn>
package:stack_trace  Chain.capture
main.dart 10:16      main.<async>

我做错了吗?链是否与整个异步/等待事物不兼容?

2 个答案:

答案 0 :(得分:3)

您使用的是什么版本的Dart和stack_trace?在使用1.9.0-edge.44028 stack_trace的Dart 1.2.3上删除console_test行后,我得到以下输出:

test.dart 16:3       testFunction.<async>
dart:async           _Completer.completeError
test.dart 17:2       testFunction.<async>
dart:async           Future.Future.microtask
test.dart 7:25       main.<async>.<fn>.<async>
package:stack_trace  Chain.capture
test.dart 5:16       main.<async>

还值得注意的是,您并非真的需要Trace.formatChain一起使用。您可以使用Chain.terse,这也将保留异步间隙。

答案 1 :(得分:0)

@ nex3正确地指出我的原始示例实际上在Dart的1.9.0 dev构建中工作,所以这可能只是目前的不兼容性。无论如何,从Chain.capture取消async,将testFunction()上的await更改为return并在Chain.Capture上使用await实际上会产生正确的输出。这显然不是100%最优,但它可以完成工作。

main() async {
  print('Hello world: ${console_test.calculate()}!');
  var test = await Chain.capture(() {
    return testFunction();
  },
  onError: (e, stackTrace) => print(Trace.format(new Chain.forTrace(stackTrace))));
  print(test);
}

Future testFunction() async {
  return "nice!";
  throw new Exception("TEST");
}