Could someone please take 5 minutes and explain the difference between throwing errors and exceptions in Flutter/Dart. The information I find online is very contradictory and confusing.
-
In which cases should I throw an Error, in which cases should I throw an exception?
-
Which of those can or should be caught by try/catch approach?
-
What is the difference between throwing the difference error types, for instance an Error or an ArgumentError? Where can I find a list of these types?
Many thanks in advance!
2
Answers
Errors show critical issues that a program shouldn’t attempt to catch. Usually, these are problems with the code itself, such as malfunctioning systems or logical errors.
Exceptions are situations, such as incorrect user input or unsuccessful network requests, that a program may wish to detect and handle.
When to throw what?
Throw an error: when there is an issue with your code — such as an AssertionError or TypeError — cannot be fixed.
Throw an exception: When you face an issue that may wish to handle or recover from (such as an IOException or FormatException).
Using try/catch:
Catch Exceptions: To handle exceptions, use the try/catch block. This lets you inform the user.
Avoid Catching: Errors are typically not meant to be caught.
In short,
Errors: serious, not usually caught.
Exceptions: Less serious, can be caught and handled.
For more detailed information, check here.
Error
s are for logical errors made by the programmer. They are for conditions that should not logically occur. Throw them for preventable situations that shouldn’t happen if code properly follows API contracts.Exception
s are for runtime errors. Throw them for situations that are out of your control (such as user input, responses from servers, unexpected data when reading a file, …).From the documentation:
and from Effective Dart:
One reason why the distinction matters is that in principle, an optimizer could remove
Error
conditions from the code since they should not logically occur and therefore can be considered to be dead code.A few rules of thumb:
Would your program in principle (in the absence of other bugs) behave the same if the
throw
ing code didn’t exist? If so, then use anError
.Do you expect the thrown object to be caught? Do you expect something in the callstack to be able to recover? If so, then use an
Exception
.Now, there are some cases that could be considered gray areas. For example, a user could enter invalid input that is passed to a function that cannot handle it. Is that a logical error or a runtime error? Whose responsibility is it to check for that invalid input, the caller’s or the callee’s? It depends on the contract of the function. Does its API documentation state that it must not be called with certain inputs? If so, then the caller is responsible for verifying those inputs first.
You should not catch
Error
s. From Effective Dart:There is not going to be any exhaustive list of all
Error
types since anybody can make their own custom class thatimplements Error
. You can see a list of the built-inError
types by looking at theError
documentation and looking at its "Implementers" list.