Description
2020-03-23 - Rewritten to state the actual change decided upon.
Summary
The runZoned
method will not have an onError
parameter. A runZonedGuarded
function is added which has an onError
parameter.
The IOOverrides
and HttpOverrides
static run*
methods will not have onError
or zoneSpecification
parameters.
What is changing:
The runZoned
method is declared as
R runZoned<R>(
R body(), {
Map zoneValues,
ZoneSpecification zoneSpecification
})
and we add:
R? runZonedGuarded<R>(
R body(),
void onError(Object error, StackTrace stack), {
Map zoneValues,
ZoneSpecification zoneSpecification,
})
The static methods from dart:io
have their zoneSpecification
and onError
parameters removed.
Why is this changing?
The existing uses of runZoned
can be split into two groups: Those with onError
and those without.
Those without an onError
always return the result of calling body
. Those with onError
return either that or null
.
In Null Safe code, using the same function for both operations would require the return type to always be nullable, which makes the first group unnecessarily cumbersome.
Other workarounds are either fragile or surprising (for example, as originally proposed, throwing if the R
type is not nullable and returning null
if not).
This change is larger, but ends up with a better API for Null Safety.
The dart:io
override classes would have to split their static run*
methods in the same way to be compatible. Instead it was decided that the onError
and zoneSpecification
parameters were not used often enough for them to carry their own weight. Removing them gives a better API, and users can still use the dart:async
runZoned
/runZonedGuarded
methods as well, if necessary.
Expected impact
Code which uses runZoned
with an onError
argument to catch synchronous errors will need to call runZonedGuarded
instead.
Migration
For now, the onError
parameter is only @deprecated
, and in the Null Safe SDK is made to throw if catching a synchronous error and the return type is not nullable. Existing code should keep running until it is migrated to using runZonedGuarded
.
When enough code has been migrated off the deprecated member, it will be removed entirely in a separate CL.