Catch an exception in the test code using flutter integration driver - flutter

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);
};

Related

Error debugging Flutter in Visual Studio Code

When debugging an async function, when there is a line with await, it can't debug the next line and I never get to know the response body. If I make a break point either. And this is happening to me in all lines with await.
#override
Future getCountries() async {
try {
final response = await httpCache(
'$domain/wp-json/api/flutter_user/get_countries'.toUri()!);
var body = convert.jsonDecode(response.body);
return body;
} catch (err) {
rethrow;
}
}
Know if there is any configuration to debug asynchronous functions in Flutter with VSCode.

How to ignore the exception in flutter integration test & continue the test execution

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.!

Flutter&Dart Catch Block does not catch thrown Exception

I am trying to catch thrown exception when server does not return 200 status code. Here is the code:
late Future<List<Data>> datasFuture;
String _warning = "";
#override
void initState() {
try {
datasFuture = RestfulServiceProvider.fetchDatas();
} on Exception {
_warning = "There is no data to fetch!";
}
super.initState();
}
//RestfulServiceProvider class
static Future<List<Data>> fetchDatas() async {
List jsonResponse = [];
final response =
await http.get(Uri.parse('http://localhost:8080/datas'));
if (response.statusCode == 200) {
jsonResponse = json.decode(response.body);
return jsonResponse.map((data) => Data.fromJson(data)).toList();
} else {
throw Exception();
}
}
When exception occurs code does not go in on Exception block, I cant handle the error. Any idea or solutions? thanks.
Try-catch block can catch exceptions occured in the bounds of its block. Your will not catch error because you are just assigning Future to a variable ( not awaiting its value ). So can the block catch exceptions from single assignment operation? No. Variable is just assigned and the program moves on and quits try-catch block immediately. You must await the value to catch it the block - awaiting it. But you can not use async-await syntax directly inside initState. So you have 2 options:
catchError of Future
RestfulServiceProvider.fetchDatas().catchError((error){Your code here}));
Utilizing it into another function with async-await
void someFunc () async{
try {
await RestfulServiceProvider.fetchDatas();
} on Exception catch(e) {
_warning = "There is no data to fetch!";
}
}
And call it in initState

Flutter http exception not throw on another try catch block

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

Sentry is NOT reporting error inside Flutter

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