-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Future.catchError unsafe if you don't know the runtimeType of the Future it is called on #51248
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
Comments
Related issue: #50430 |
Correct. First of all, the parameter of Even if it had a useful type like A solution would be to introduce super-bounded type parameters, and make Future<R> catchError<R super T>(FutureOr<R> Function(Object, StackTrace) handleError, ...) We're not close to getting that, so not a solution. |
We have the extension method Ideally this shouldn't impact much code because it would use Is the bug that we should be more careful that the runtime type for a |
Ooh, I think this would fix our use case. With this change, I think |
The Rewriting it to be even more type safe should be possible, preferably more efficiently than introducing an intermediate future. |
We will need a backup implementation for non |
True, the backup could do the extension _<T> on Future<T> {
Future<T> onError<E extends Object>(FutureOr<T> Function(E, StackTrace) onError, [bool Function(E)? test]) =>
this.then<T>((T value) => value, onError: (Object error, StackTrace stack) {
if (error is! E || test != null && !test(error)) throw error; // Rethrow.
return onError(error, stack);
});
} I should just change it to that. The biggest inefficiency here is allocating the |
Would be great if you made this change. I basically implemented that code inline in all the places we were using |
….catchError (#140122) Ensure tool code does not use Future.catchError or Future.onError, because it is not statically safe: dart-lang/sdk#51248. This was proposed upstream in dart-lang/linter in https://github.com/dart-lang/linter/issues/4071 and dart-archive/linter#4068, but not accepted.
(The |
Thanks! |
Update April 3, 2024
The Future.onError extension method now solves this problem--that is, this code works without throwing an Error:
Consider the following code:
This code appears to be statically correct. Because the return type of
handler
satisfies the return type offunc()
, it looks like this code should work. However, at runtime, the.catchError
method will actually be called on aFuture<bool>
, and now ourhandler
function is no longer a valid callback toFuture<bool>.catchError()
, and we get anArgumentError
:Even though the
onError
extension method features a strictly-typed callback, it still leads to a runtime-only error:Leads to the same stacktrace.
Interestingly, passing our handler to the
onError
parameter of.then()
does not have the runtime error:This has lead to a series of very difficult to track down crashes in the Flutter CLI tool (especially since the stacktrace is opaque), such as flutter/flutter#114031
In this particular case, we were doing essentially:
The text was updated successfully, but these errors were encountered: