Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use catch anymore when using Chain.capture #112

Open
fzyzcjy opened this issue Jul 25, 2021 · 2 comments
Open

Cannot use catch anymore when using Chain.capture #112

fzyzcjy opened this issue Jul 25, 2021 · 2 comments

Comments

@fzyzcjy
Copy link

fzyzcjy commented Jul 25, 2021

Very simple example:

void main() async {
  try {
    await g();
  } catch (e) {
    print('catch e=$e');
  }
}

Future<void> g() {
  throw Exception('fake error');
}

As expected, the output is catch e=Exception: fake error.

However, by wrapping g with Chain.capture as follows:

Future<void> g() {
  return Chain.capture(() async {
    throw Exception('fake error');
  });
}

Our catch no longer works! See below:

[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: Exception: fake error
package:yplusplus/main.dart 60:5              g.<fn>
package:yplusplus/main.dart 59:24             g.<fn>
package:stack_trace/src/chain.dart 94:24      Chain.capture.<fn>
dart:async/zone.dart 1354:13                  _rootRun
dart:async/zone.dart 1258:19                  _CustomZone.run
dart:async/zone.dart 1789:10                  _runZoned
dart:async/zone.dart 1711:10                  runZoned
package:stack_trace/src/chain.dart 92:12      Chain.capture
package:yplusplus/main.dart 59:16             g
package:yplusplus/main.dart 52:11             main
dart:ui/hooks.dart 142:25                     _runMainZoned.<fn>.<fn>
dart:async/zone.dart 1354:13                  _rootRun
dart:async/zone.dart 1258:19                  _CustomZone.run
dart:async/zone.dart 1789:10                  _runZoned
dart:async/zone.dart 1777:12                  runZonedGuarded
dart:ui/hooks.dart 138:5                      _runMainZoned.<fn>
dart:isola<…>

This is very counter-intuitive. I wonder how can I solve this problem? In other words, I want to have the full stack trace (so I use capture), but at the same time, I want catch to work!

Thanks for any suggestions!

@blaugold
Copy link

Chain.capture creates a new error zone and runs the given function in it, if invoked with the default arguments. Errors cannot cross error zones, so awaiting the result of Chain.capture cannot catch errors and any errors are unhandled exceptions in the error zone created by Chain.capture.

You can disable the creation of a new error zone with Chain.capture(..., errorZone: false).

@Tienisto
Copy link

Tienisto commented Sep 3, 2023

@blaugold Your solution with errorZone: false will make it "catchable" again but we lose the "stack chains" feature advertised by this library.

Is there any way to have the full async stack trace while also catchable?

Edit:

I found a solution:

Never rethrowWithNewStackTrace(Object error, StackTrace stackTrace) {
  Error.throwWithStackTrace(
    error,
    StackTrace.fromString(
      '$stackTrace===== asynchronous gap ===========================\n${StackTrace.current}',
    ),
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants