Given the shortcode example below:
... print("1 parsing stuff"); List<dynamic> subjectjson; try { subjectjson = json.decode(response.body); } on Exception catch (_) { print("throwing new error"); throw Exception("Error on server"); } print("2 parsing stuff"); ... I would expect the catch block to execute whenever the decoding fails. However, when a bad response returns, the terminal displays the exception and neither the catch nor the continuation code fires...
flutter: 1 parsing stuff [VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>' What am I missing here?
36 Answers
Functions can throw anything, even things that aren't an Exception:
void foo() { throw 42; } But the on Exception clause means that you are specifically catching only subclass of Exception.
As such, in the following code:
try { throw 42; } on Exception catch (_) { print('never reached'); } the on Exception will never be reached.
It is not a syntax error to have on Exception catch as someone else answered. However you need to be aware that the catch will not be triggered unless the error being thrown is of type Exception.
If you want to find out the exact type of the error you are getting, remove on Exception so that all errors are caught, put a breakpoint within the catch and check the type of the error. You can also use code similar to the following, if you want to do something for Exceptions, and something else for errors of all other types:
try { ... } on Exception catch (exception) { ... // only executed if error is of type Exception } catch (error) { ... // executed for errors of all types other than Exception } 2Use:
try { ... } on Exception catch (exception) { ... // only executed if error is of type Exception } catch (error) { ... // executed for errors of all types other than Exception } 2 print("1 parsing stuff"); List<dynamic> subjectjson; try { subjectjson = json.decode(response.body); } catch (_) { . // <-- removing the on Exception clause print("throwing new error"); throw Exception("Error on server"); } print("2 parsing stuff"); ... This works, but what is the rationale behind this? Isn't the type inconsistency an Exception?
1The rule is that exception handling should be from detailed exceptions to general exceptions in order to make the operation to fall in the proper catch block and give you more information about the error, like catch blocks in the following method:
Future<int> updateUserById(int userIdForUpdate, String newName) async { final db = await database; try { int code = await db.update('tbl_user', {'name': newName}, whereArgs: [userIdForUpdate], where: "id = ?"); return code; } on DatabaseException catch(de) { print(de); return 2; } on FormatException catch(fe) { print(fe); return 2; } on Exception catch(e) { print(e); return 2; } } As everybody or most of the people said, try to know exactly what error you are getting:
try{ } catch(err){ print(err.runTimeType); } runTimeType will give you the type of data or exception you are getting or to put simple the exception itself. And then do whatever you want. (Like if you are not getting the exception of what you expected, then try to fix that issue or change the exception.)
Another option is to go with general form. Using the simple catch which will prompt every time.