Home > Mobile >  Exception thrown by async function is intercepted by crashlytics
Exception thrown by async function is intercepted by crashlytics

Time:08-04

I have the following function:

class CannotOpenMapException implements Exception {}

void launchMap(String address) async {
  …
  throw CannotOpenMapException();
}

And then in an onTap handler:

onTap: () {
  try {
    launchMap(my_address);
  } on CannotOpenMapException {
    print('caught exception!');
  }
}

Thing is, the exception is not caught, the print statement is never executed.

I think the problem is with the way I start Crashlytics (though this is how the official docs recommend it):

void main() async {
  runZonedGuarded<Future<void>>(() async {
    FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
    …
    runApp(const MyApp());
  },
    (error, stack) =>
        FirebaseCrashlytics.instance.recordError(error, stack, fatal: true));
}

Is there a way I can make Crashlytics only catch the exception I don't catch?

CodePudding user response:

You should use the second argument "onError" of runZoneGuarder, this way only the exceptions that's you don't catch are intercepted.

runZonedGuarded<Future<void>>(() async {
    WidgetsFlutterBinding.ensureInitialized();
    ... and stuff

    runApp(const MyApp());
  }, (error, stack) {
    FirebaseCrashlytics.instance.recordError(error, stack);
  });

The doc: https://api.flutter.dev/flutter/dart-async/runZonedGuarded.html

CodePudding user response:

I found the problem: The onTap handler was not async, so it just started launchMap and then exited. Now the launchMap execution was running "detached" (not sure that is the correct word for it). In order to catch it, onTap needs to be async and use the await keyword:

onTap: () async {
  try {
    await launchMap(widget.listing.address());
  } on CannotOpenMapException {
    …
  }
})

CodePudding user response:

onTap: () {
try {
await launchMap(my_address);
} on CannotOpenMapException {
print('caught exception!');
}
}

if you want to use async then use await.

  • Related