Error vs. Exception in Dart

From this post, quoting Bob Nystrom:

Error and its subclasses are for programmatic errors. If one of those occurs, your code is bad and you should fix your code.

Non-Error exception classes are for runtime errors. Sometimes you can prevent them from being thrown, but often you cannot.

Except in a few special circumstances, idiomatic Dart should throw Errors, but never catch them. They exists specifically to not be caught so that they take down the app and alert the programmer to the location of the bug.

In other words, you should expect (and check for) exceptions (it is intended that you should handle them). If you get an error, then you need to check how you're using the API that's throwing the error - you're probably using it wrong.

If you're writing an API, then you should use the same pattern. Errors are messages to downstream developers about how they are using your API.


Exception

An Exception in Dart should be thrown for regular, expected program flow and is intended to be caught:

An Exception is intended to convey information to the user about a failure, so that the error can be addressed programmatically. It is intended to be caught, and it should contain useful data fields.

Example: TimeoutException

A TimeoutException will be thrown "when a scheduled timeout happens while waiting for an async result", which is expected program flow.
If we have a download task for example and that download task is not finished after our specified timeout time of thirty seconds (which can happen), we want to communicate that to our user, hence, we need to catch the Exception.

Error

An Error in Dart should be thrown for unexpected program flow and should not be caught but addressed by the programmer:

An Error object represents a program failure that the programmer should have avoided.

Example: AssertionError

An AssertionError is thrown "when an assert statement fails", i.e. it should never happen because we assert that it should not.
If we see such an error, it means that we should change our code and we should definitely not catch the error.


In practice you can catch Errors, but you should not. There is a linter rule to help enforce that.
The fact that Dart allows it can still be useful, e.g. when testing assertions or other errors.


See this answer for a complete example scenario.

Tags:

Dart