【问题标题】:How to get the full stack trace for async execution如何获取异步执行的完整堆栈跟踪
【发布时间】:2015-05-14 20:02:02
【问题描述】:

举个小例子

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

void main() {
  scheduleAsync();
}

void scheduleAsync() {
  new Future.delayed(new Duration(seconds: 1))
      .then((_) => runAsync());
}

void runAsync() {
  throw 'oh no!';
}

我得到了这个堆栈跟踪。我能追踪到的最远回叫是scheduleAsync() 中的runAsync() 调用。 没有留下任何信息,scheduleAsync 是从 main 调用的。

未处理的异常: 未捕获的错误:哦,不! 堆栈跟踪: #0 runAsync (file:///home/myuser/dart/playground/bin/stack_trace/main.dart:14:3) #1 调度异步。 (file:///home/myuser/dart/playground/bin/stack_trace/main.dart:10:28) #2 _RootZone.runUnary (dart:async/zone.dart:1155) #3 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:484) #4 _Future._propagateToListeners (dart:async/future_impl.dart:567) #5 _Future._complete (dart:async/future_impl.dart:348) #6 Future.Future.delayed。 (dart:async/future.dart:228) #7 定时器._createTimer。 (dart:async-patch/timer_patch.dart:16) #8 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:385) #9 _handleMessage (dart:isolate-patch/timer_impl.dart:411) #10 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:142) #0 _rootHandleUncaughtError。 (dart:async/zone.dart:886) #1 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41) #2 _asyncRunCallback (dart:async/schedule_microtask.dart:48) #3 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96) #4 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:392) #5 _handleMessage (dart:isolate-patch/timer_impl.dart:411) #6 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:142) 进程以退出代码 255 结束

有没有办法获得完整的堆栈跟踪?

【问题讨论】:

标签: dart dart-async


【解决方案1】:

stack_tracehttps://pub.dartlang.org/packages/stack_trace 将整个堆栈跟踪放在一起。

另见
- this blog post 来自 stack_trace 包的开发人员。
- http://news.dartlang.org/2016/01/unboxing-packages-stacktrace.html?m=1

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

void main() {
  Chain.capture(() {
    scheduleAsync(); // <= pass my code in Chain.capture
    }, onError: (error, stack) {
      print(error);
      print(stack);
    });
}

void scheduleAsync() {
  new Future.delayed(new Duration(seconds: 1))
      .then((_) => runAsync());
}

void runAsync() {
  throw 'oh no!';
}

产生这个输出,它允许追溯到main 中的第一行。

不好了! main.dart 19:3 runAsync main.dart 15:28 scheduleAsync。 包:stack_trace/src/stack_zone_specification.dart 134:26 registerUnaryCallback.. 包:stack_trace/src/stack_zone_specification.dart 210:15 StackZoneSpecification._run 包:stack_trace/src/stack_zone_specification.dart 134:18 registerUnaryCallback。 dart:async/zone.dart 902 _rootRunUnary dart:async/zone.dart 804 _CustomZone.runUnary dart:async/future_impl.dart 484 _Future._propagateToListeners.handleValueCallback dart:async/future_impl.dart 567 _F​​uture._propagateToListeners dart:async/future_impl.dart 348 _Future._complete dart:async/future.dart 228 Future.Future.delayed。 包:stack_trace/src/stack_zone_specification.dart 210:15 StackZoneSpecification._run 包:stack_trace/src/stack_zone_specification.dart 124:52 registerCallback。 dart:async/zone.dart 891 _rootRun dart:async/zone.dart 796 _CustomZone.run dart:async/zone.dart 704 _CustomZone.runGuarded dart:async/zone.dart 729 _CustomZone.bindCallback。 包:stack_trace/src/stack_zone_specification.dart 210:15 StackZoneSpecification._run 包:stack_trace/src/stack_zone_specification.dart 124:52 registerCallback。 dart:async/zone.dart 895 _rootRun dart:async/zone.dart 796 _CustomZone.run dart:async/zone.dart 704 _CustomZone.runGuarded dart:async/zone.dart 729 _CustomZone.bindCallback。 dart:async-patch/timer_patch.dart 16 Timer._createTimer。 dart:isolate-patch/timer_impl.dart 385 _Timer._runTimers dart:isolate-patch/timer_impl.dart 411 _handleMessage dart:isolate-patch/isolate_patch.dart 142 _RawReceivePortImpl._handleMessage ===== 异步间隙 ============================ dart:async/zone.dart 828 _CustomZone.registerUnaryCallback 飞镖:异步/future_impl.dart 208 _Future.then main.dart 15:12 scheduleAsync main.dart 6:18 主要。 包:stack_trace/src/chain.dart 82:24 Chain.capture。 dart:async/zone.dart 895 _rootRun dart:async/zone.dart 796 _CustomZone.run dart:async/zone.dart 1251 运行分区 包:stack_trace/src/chain.dart 80:20 Chain.capture main.dart 5:16 主要 dart:isolate-patch/isolate_patch.dart 255 _startIsolate。 dart:isolate-patch/isolate_patch.dart 142 _RawReceivePortImpl._handleMessage 进程以退出代码 0 结束

简洁版更有用

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

void main() {
  Chain.capture(() {
    scheduleAsync();
    }, onError: (error, stack) {
      print(error);
      print(new Trace.from(stack).terse);
    });
}

void scheduleAsync() {
  new Future.delayed(new Duration(seconds: 1))
      .then((_) => runAsync());
}

void runAsync() {
  throw 'oh no!';
}

产生:

不好了! main.dart 19:3 runAsync main.dart 15:28 scheduleAsync。 ===== 异步间隙 ============================ 飞镖:异步_Future.then main.dart 15:12 scheduleAsync main.dart 6:18 主要。 包:stack_trace Chain.capture main.dart 5:16 主要 进程以退出代码 0 结束

【讨论】:

  • 您正在将异步函数scheduleAsync() 传递给链。我在这里误解了什么吗?关键是要知道错误的来源,如果您必须指定它违背目的的来源。
  • 您只需将整个应用程序包装在Chain.capture(...) 中,而scheduleAsync 是替换main(),所有代码都从那里开始,所以这是您唯一需要这样做的地方覆盖。
  • 嗨@Günter Zöchbauer,感谢您的回答!我应用了它并且有效!但是,有一种情况它不起作用!请检查我的问题stackoverflow.com/questions/67751416/…
猜你喜欢
  • 2011-08-30
  • 2021-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多