-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Breaking change request] The runZoned method will now not catch synchronously thrown errors even when given an error handler. #40681
Comments
cc @Hixie @matanlurey @dgrove @vsmenon for review and approval. |
It's not really clear to me when you would intentionally use onError with runZoned and expect a synchronous return value, other than the specific case of wanting to have the handler handle the error and the call to return null. |
@Hixie Not sure I understand. The current uses of
The third item is the one that we cannot support with null safe types without making the return type nullable ( If we change the return type to In languages with overloading, it would not be a problem because they would just have a version without We could introduce a second |
If it was up to me I think my proposal would be to deprecate runZoned entirely and have two alternatives, one without error handling that returns a non-nullable value, and one with error handling that returns a nullable value. That said, it seems Zone already has a more elaborate API here. Indeed, runZoned and Zone.run, Zone.runGuarded, et al, are quite different in semantics and that seems unnecessarily inconsistent. I think we should probably just rationalize these two APIs so that they are equivalent. If we do that, then we can simultaneously make sure that our new API is rational in an NNBD world (e.g. looks like Zone.runGuarded returns void, not R, and so side-steps the problem; why can't we do the same here?). |
We can do a lot of things if we want to change or replace The one thing we cannot do is to keep it working like it does now (sometimes returning That does suggest another approach: Make the return type So: /// Keeps working like now. Perhaps deprecate it.
R? runZoned<R>(R body(), { ... }) ...
/// Captures all errors, sync or async. Returns nothing.
void runZonedGuarded(void body(), {..., void onError(Object error, StackTrace trace)}) ...
/// Captures async errors only
R runZonedWith(R body(), { ..., void onError(Object error, StackTrace trace)}) ... |
How about: /// Captures all errors, sync or async. Returns nothing.
void runZonedGuarded(void body(), {..., void onError(Object error, StackTrace trace)}) ...
/// Does not capture errors (no error handler).
R runZoned(R body(), { ... }) ... If I understand the Zone API correctly, that would at least be consistent with Zone's |
I like the APIs. It's what I was going for above, but without keeping the legacy function around. That's also the biggest issue. This would be a hard breaking change since the That suggests a two-step migration:
The we won't remove the (The |
LGTM. |
lgtm for dart |
I don't have a strong opinion, though we have a ton of magic "Zone" code throughout google3; in fact I see at least 200+ occurrences. I would feel better like Hixie mentioned if we had |
Approved |
That's two votes for I'll wrap up a CL for that (https://dart-review.googlesource.com/c/sdk/+/137302) with an API like: R runZoned<R>(
R body(),
{ZoneSpecification zoneSpecification,
ZoneVariables zoneValues}) { ... }
R? runZonedGuarded<R>(
R body(),
Function onError,
{ZoneSpecification zoneSpecification,
ZoneVariables zoneValues}) { ... } as the NNBD API, and backported as R runZoned<R>(
R body(),
{ZoneSpecification zoneSpecification,
ZoneVariables zoneValues,
@Deprecated("Use runZonedGuarded instead')
Function onError}) { ... }
R? runZonedGuarded<R>(
R body(),
Function onError,
{ZoneSpecification zoneSpecification,
ZoneVariables zoneValues}) { ... } I agree that it is a better API. It's a potentially more breaking change. Looking through the SDK alone, there are numerous places which needs to be migrated. I count 16 files in 9 packages in the SDK pkg/ directory which are using I fear that migration will be very expensive. The function which corresponds to the current usage is named differently, so migration has to happen before the platform library unforking. |
@Hixie Was your LGTM for the original proposal, or for the alternative with |
@Hixie @matanlurey Do I understand this as you are both in support of the API proposed here? cc @natebosch |
One thing that still isn't clear to me with either proposal: The |
The The The With no That's why the |
Since |
@natebosch That is a very good idea. |
I just noticed that the That API should proably also be changed to |
I would strongly prefer this. The API is considerably less confusing if we don't try to mix responsibilities. (I'd also prefer we hadn't add 2 flavors of the API just for HttpOverrides, but oh well). We aren't going to break much, if any, code removing these arguments. Usage is incredibly low. I cannot find a single call to either API that includes these arguments. |
The new proposal is now available as https://dart-review.googlesource.com/c/sdk/+/137302 It breaks building the SDK in NNBD mode because of the removed |
I have updated the documentation in this issue to match the CL. |
Change landed |
Breaking change in flutter 1.17.0. For more information, see dart-lang/sdk#40681.
2020-03-23 - Rewritten to state the actual change decided upon.
Summary
The
runZoned
method will not have anonError
parameter. ArunZonedGuarded
function is added which has anonError
parameter.The
IOOverrides
andHttpOverrides
staticrun*
methods will not haveonError
orzoneSpecification
parameters.What is changing:
The
runZoned
method is declared asand we add:
The static methods from
dart:io
have theirzoneSpecification
andonError
parameters removed.Why is this changing?
The existing uses of
runZoned
can be split into two groups: Those withonError
and those without.Those without an
onError
always return the result of callingbody
. Those withonError
return either that ornull
.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 returningnull
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 staticrun*
methods in the same way to be compatible. Instead it was decided that theonError
andzoneSpecification
parameters were not used often enough for them to carry their own weight. Removing them gives a better API, and users can still use thedart:async
runZoned
/runZonedGuarded
methods as well, if necessary.Expected impact
Code which uses
runZoned
with anonError
argument to catch synchronous errors will need to callrunZonedGuarded
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 usingrunZonedGuarded
.When enough code has been migrated off the deprecated member, it will be removed entirely in a separate CL.
The text was updated successfully, but these errors were encountered: