What is the correct way to catch both Error and Exception following `effective dart`?

513

re-posting the answer from @Miyoyo on r/FlutterDev discord

Optimally? You do not catch error
Just, at all
Remember effective dart is Guidelines
Using them as gospel will make some things impossible
Catching error is deliberately made to be "not according to guidelines"

because you're not supposed to do that

for my use case I'll just add

// ignore_for_file: avoid_catching_errors

Share:
513
Francesco Iapicca
Author by

Francesco Iapicca

Updated on December 01, 2022

Comments

  • Francesco Iapicca
    Francesco Iapicca over 1 year

    this code sample

    import 'package:flutter_test/flutter_test.dart';
    
    void main() {
      const one = 1;
      String oneAsString() => one as String;
    
      test('Make sure it fails', () {
        var s;
        var _e;
        try {
          s = oneAsString();
        } on Error catch (e) {
          _e = e;
        }
        expect(s == null, true, reason: 'should fail');
        expect(_e == null, false, reason: 'error or exception should be returned');
      });
    
      test('Catchin Error', () {
        var _e;
        try {
          oneAsString();
        } on Error catch (e) {
          _e = e;
        }
        expect(_e is Error, true, reason: 'should be an error');
      });
    
      test('Catchin Exception', () {
        var _e;
        try {
          oneAsString();
        } on Exception catch (e) {
          _e = e;
        }
    
        expect(_e is Exception, true, reason: 'should be an exception');
      });
    
      test('Why not BOTH', () {
        var _e;
        try {
          oneAsString();
        } on Error catch (e) {
          _e = e;
        } on Exception catch (e) {
          _e = e;
        }
    
        expect(_e is Error, true, reason: 'should be an error');
        expect(_e is Exception, false, reason: 'should NOT be an exception');
      });
    }
    
    

    outputs this result

    00:02 +2 -1: Catchin Exception [E]                                                                                                                                                                          
      type 'int' is not a subtype of type 'String' in type cast
      test/widget_test.dart 5:31   main.oneAsString
      test/widget_test.dart 31:18  main.<fn>
      
    00:02 +3 -1: Some tests failed.   
    

    the safest approach seems to be Why not BOTH, but following effective dart
    (enforcing it with the package effective_dart)
    the analysis complains about avoid_catching_errors

    DON'T explicitly catch Error or types that implement it.

    Errors differ from Exceptions in that Errors can be analyzed and prevented prior to runtime. It should almost never be necessary to catch an error at runtime.

    BAD:

    try { somethingRisky(); } on Error catch(e) { doSomething(e); } GOOD:

    try { somethingRisky(); } on Exception catch(e) { doSomething(e); }

    and if I simple do

    try {} catch (e) {}
    

    the analyzer complains about avoid_catches_without_on_clauses

    AVOID catches without on clauses.

    Using catch clauses without on clauses make your code prone to encountering unexpected errors that won't be thrown (and thus will go unnoticed).

    BAD:

    try { somethingRisky() } catch(e) { doSomething(e); } GOOD:

    try { somethingRisky() } on Exception catch(e) { doSomething(e); }

    what is the correct approach to catch BOTH Error and Exception?