I have my Sentry setup like this:
void main() => runZonedGuarded(() {
runApp(MyApp());
}, (Object error, StackTrace stackTrace) {
reportError(error, stackTrace);
});
and related functions
final SentryClient sentry = new SentryClient(dsn: '<my-dsn>');
Future<void> reportError(dynamic error, dynamic stackTrace) async {
sentry.captureException(
exception: error,
stackTrace: stackTrace,
);
}
I added throw Exception("my-error") inside a widget's build method, I can't see the error is showing on the Sentry web console.
I create a single file to throw exception and sentry capture, and I do see sentry is reporting the error.
Something must wrong with runZonedGuarded.
Check in your sentry dashboard if you are using the free version and if the monthly quota hasnt been surpassed. If that is the case you will not receive any events.
After a number of Sentry setups that didn't seem to work right, I arrived at this one that works:
Future<void> main() async {
final sentry = Sentry.SentryClient(Sentry.SentryOptions(dsn: '[Add dsn URI here]'));
runZonedGuarded(() {
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (FlutterErrorDetails errorDetails) {
sentry.captureException(
errorDetails.exception,
stackTrace: errorDetails.stack,
);
};
runApp(MyApp());
}, (Object error, StackTrace stackTrace) {
sentry.captureException(
error,
stackTrace: stackTrace,
);
});
}
you must make the func async to send error to sentry console
be sure import this file for mobile app:
import 'package:sentry/io_client.dart';
E.g:
main.dart
import 'package:sentry/io_client.dart';
final SentryClient sentry = new SentryClient(dsn: YOUR_DSN);
main() async {
try {
throw new StateError('This is a Dart exception.');
} catch(error, stackTrace) {
await sentry.captureException(
exception: error,
stackTrace: stackTrace,
);
}
}
HomeScreen
floatingActionButton: FloatingActionButton(
onPressed: () async{
throw new StateError('This is a Dart exception.');
},
By the way in release version it will send every exception, because in debug flutter doesn't catch every error that displays in the console, and to simplify that for you can use one of these packages :
https://pub.dev/packages/catcher
https://pub.dev/packages/flutter_sentry
Related
I'm getting FirebaseException is CAUGHT BY FLUTTER TEST FRAMEWORK, while flutter integration test is being run.!
Can anybody help in understading how to ignore the FirebaseException in integration test and continue the rest of execution?
I tried below walkaround,
Future<void> restoreFlutterError(Future<void> Function() call) async {
FlutterError.onError = (FlutterErrorDetails data) {
if (data.exception is FirebaseException) {
return;
}
FlutterError.presentError(data);
};
}
And called above method in testWidgets by
testWidgets('test execution', (tester) async {
await restoreFlutterError(() async {
app.main();
await tester.pumpAndSettle(const Duration(seconds: 10));
});
...
...
});
But getting below error.!
A test overrode FlutterError.onError but either failed to return it to its original state, or had unexpected additional errors that it could not handle. Typically, this is caused by using expect() before restoring FlutterError.onError.
Any helps appreciated.!
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?
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
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 {
…
}
})
onTap: () {
try {
await launchMap(my_address);
} on CannotOpenMapException {
print('caught exception!');
}
}
if you want to use async then use await.
I am using the flutter integration driver to write the test cases for flutter web application. When the page is loading, the system throws an exception as "ImageCodeException: Failed to decode image data". But when I execute the dev code itself, that exception is caught.
void main(){
IntegrationTestWidgetsFlutterBinding.ensureInitialization();
group('Test scenario .....',(){
testWidgets('Home',(WidgetTester tester)asynsc{
app.main(); // exception throws calling this line
tester.pumpAndSettle();
});
});
try/catch
void main(){
IntegrationTestWidgetsFlutterBinding.ensureInitialization();
group('Test scenario .....',(){
testWidgets('Home',(WidgetTester tester)asynsc{
try{
app.main(); // exception throws calling this line
catch(Exception){}
tester.pumpAndSettle();
});
});
tester.takeException
void main(){
IntegrationTestWidgetsFlutterBinding.ensureInitialization();
group('Test scenario .....',(){
testWidgets('Home',(WidgetTester tester)asynsc{
tester.takeException() // or
app.main(); // exception throws calling this line
tester.takeException() // or
tester.pumpAndSettle();
});
});
I tried with try/catch , tester.takeException(). But they did not work. How can I catch an exception in the test code, please ?
Exception details : widgetTester.Exception is called , the above exception will be ignored etc..
You should override FlutterError.onError. An example below, that allows you to catch FlutterError with certain messages, can be changed to arbitrary exceptions:
FlutterError.onError = (FlutterErrorDetails data) {
if (data.exception is FlutterError) {
final fErr = data.exception as FlutterError;
if (fErr.message == '...') {
// do not forward to presentError
return;
}
}
FlutterError.presentError(data);
};
I get into this weird exception which keeps on coming and freezing my app.
I am try to handle SocketException and TimeOutException in http package with provider package.
class Auth with ChangeNotifier{
..........
Future<User> getUser(String id) async {
try {
final user = (await http.post("${Domain.ADDRESS}/user",
headers: {"auth-token": _token}, body: {"userId": id}))
.body;
} on SocketException {
throw HttpException("DISCONNECTED");
} on TimeoutException {
throw HttpException("TIMEOUT");
} catch (error) {
print(error);
throw HttpException("SOMETHING_WENT_WRONG");
}
notifyListeners();
return userdata;
}
......
}
when internet in not connected application freezing at
on SocketException {
throw HttpException("DISCONNECTED"); <------------ Exception has occurred.
HttpException (DISCONNECTED)
But I handle this on next screen
#override
Future<void> didChangeDependencies() async {
......
setState(() {
isLoading = true;
});
try{
user= await Provider.of<Auth>(context)
.getUser(Provider.of<Auth>(context).userId);
if (this.mounted) {
setState(() {
isLoading = false;
});
}
}on HttpException catch(error){
if(error.toString().contains("DISCONNECTED")){
Scaffold.of(context).showSnackBar(SnackBar(content: Text("Please check your internet
connection"),));
}
}catch(error){
print(error);
}
super.didChangeDependencies();
}
Custom HttpException.dart
class HttpException implements Exception {
final String message;
HttpException(this.message);
#override
String toString() {
return message;
}
}
So if I understand you right, your IDE pauses when the exception is thrown, even though you catch it correctly.
Can you tell me what happens after resuming / unpausing the IDE that you're using, does it behave as expected and print this?
if(error.toString().contains("DISCONNECTED")){
Scaffold.of(context).showSnackBar(SnackBar(content: Text("Please check your internet
connection"),));
Because if it does, that means that you probably have the Breakpoints setting on All Exceptions and not only Uncaught Exceptions.
I also had this problem and I found out that it was due to a bugged flutter beta/dev version that I had.
Solution
I fixed it by changing the channel to stable and upgrading to the newest version.
flutter channel stable
flutter upgrade
If you want, you can also change the channel to master to have the newest features of flutter. But I would really suggest using the stable channel, since it is more stable and beacause a new stable build was just recently released.
Here's a link to the issue that you're encountering:
https://github.com/flutter/flutter/issues/66488
I got this error message when I using newest Flutter v 1.17.1 and Dart 2.8.2 version on main.dart file,
'onError' is deprecated and shouldn't be used. Use runZonedGuarded instead.
Try replacing the use of the deprecated member with the replacement.
and this is the code,
runZoned<Future<Null>>(() async {
runApp(MyApp());
}, onError: (error, stackTrace) async {
await FlutterCrashlytics().reportCrash(error, stackTrace, forceCrash: false);
});
}
Any solution to get rid of this error message?
You can do this:
runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}, (Object error, StackTrace stack) async {
await FlutterCrashlytics().reportCrash(error, stackTrace, forceCrash: false);
});