Description
Intended Change
Make every platform operation currently throwing a CastError
instead throw an object implementing both TypeError
and CastError
. (Effectively make all implementations of CastError
also implement TypeError
).
Deprecate CastError
and recommend that everybody uses TypeError
instead.
Implementations are allowed to use a class implementing CastError
when they throw a TypeError
, so they can decide to only have one class.
Eventually remove CastError
from the platform libraries (possibly along with other errors classes that can no longer happen, primarily AbstractClassInstantiationError
and FallthroughError
).
Rationale
Currently the Dart runtimes throw TypeError
in some situations and CastError
in other situations.
In Dart 1, the distinction was clear: TypeError
was an AssertionError
and was only thrown in checked mode when a type assertion failed, and CastError
was thrown when an as
operation failed.
In Dart 2. that distinction was no longer meaningful. Because of sound typing, a type assertion can no longer fail. If there is a risk that it can fail at run-time, the compiler inserts an implicit cast. It is as if your int x = dynamicValue;
was converted to int x = dynamicValue as int;
.
Except that the explicit cast throws CastError
and the implicit cast throws TypeError
. Maybe.
The language specification no longer mentions CastError
, simply stating that a failed as
cast is a dynamic type error, which means that it should be throwing a TypeError
.
When compiling to JavaScript, it's often necessary to convert native exceptions to Dart errors, and having to figure out whether to use a TypeError
or a CastError
is an extra unnecessary overhead.
All in all, the CastError
does not carry its own weight.
See also dart-lang/language#787.
Expected impact
No initial impact. Requires some later migration from catching CastError
to catching TypeError
before the CastError
can be removed.
Catching errors:
By making all errors that are actually thrown implement both CastError
and TypeError
, any code which currently catches CastError
or TypeError
will still catch the same errors. The only difference would be in a situation where a try
/catch
statement attempts to distinguish between the two error types by catching both, with TypeError
first, and it will now trigger the former catch clause instead of the latter.
Throwing errors:
No known code outside of the Dart SDK platform libraries are implementing or extending CastError
(or TypeError
). No known code outside of the Dart SDK throws a new CastError
. (There is code throwing a TypeError
).
Migration:
Code currently catching CastError
should instead catch TypeError
.
This is probably primarily testing doing things like expect(..., throwsA(isCastError))
.
The CastError
is marked as deprecated, so some clients might want to migrate quickly to avoid warnings. Deprecation is not a breaking change.