うちのいぬ Tech Blog

Tech Blog of Uchinoinu/My dog

How to use Exceptions

Error handling is a common and hard concern for developers.

There're some approaches to do it and Exception by try catch is one of them.

In this article, I'll introduce how to use Exceptions in terms of Effective Dart.

dart.dev

Exceptions

Exception object is included in dart:core library.

api.dart.dev

Dart has Error and Exception. The rough differences are below.

  • Error: Problem of program. You can fix it by modifying the program.
  • Exception: Not program problem. Changing the program does not always fix runtime errors.

throw Exception

Throw Exception object using throw .

throw Exception('Exception');

Catch exceotion

Catch Exception object by try...catch statement.

  try {
    throw Exception('occur exception');
  } on Exception catch (err, stacktrace) {
    print(err);
    print(stacktrace);
    rethrow;
  } finally {
    print('finish exception handlling');
  }

出力

exception: Exception: occur exception,
#0      hoge (hoge.dart:12:5)
#1      main (hoge.dart:7:3)
#2      new Future.<anonymous closure> (dart:async/future.dart:174:37)
#3      _rootRun (dart:async/zone.dart:1346:47)
#4      _CustomZone.run (dart:async/zone.dart:1258:19)
#5      _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
#6      _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1202:23)
#7      _rootRun (dart:async/zone.dart:1354:13)
#8      _CustomZone.run (dart:async/zone.dart:1258:19)
#9      _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1186:23)
#10     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#11     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:395:19)
#12     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:426:5)
#13     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

finish exception handlling

Let's try

  • try these behaviors using dartpad

dartpad.dartlang.org

Attentions

Use on clause for catch

  • By being explicit and specific about what you are trying to catch, you can prevent unexpected behavior and errors.
try {
  doSomethingBad()
}
on Exception catch(e) {
  handleException(e);
}

Error can be analyzed and handled before execution, so it is not supplemented in the code.

  • As the headline suggests, Error can be supplemented and addressed before execution.
  • This means that there is almost no need to write code to explicitly supplement Error at runtime.

dart-lang.github.io

  • However, if there is a problem with the program that needs to be fixed, throwing an Error object is recommended by effective-dart

rethrow

dart-lang.github.io

Customise Exception class

  • When developing with the Flutter library, you may see exception classes called HogeHogeException, which may be an extension of the Exception class.
  • It may be a good idea to create such classes as needed in development.
class HogeHogeException implements Exception {
  const HogeHogeException(this.message);

  final String message;

  // By overriding toString(), when you use this class and `print(e)`, you can output the content characters instead of `Instance of 'HogeHogeException'`.
  @override
  String toString() => message;

  void sendDataToLogStorage(){
    // logic
  }
}

void main() {
  try {
    throw HogeHogeException('HogeHogeExceptionです');
  } on HogeHogeException catch (exception, stacktrace) {
    print(exception);
    print(stacktrace);
    exception.sendDataToLogStorage();
  } finally {
    print('Finally');
  }
}