AsyncSnapshot.data to throw if error or no data#34626
AsyncSnapshot.data to throw if error or no data#34626tvolkert merged 7 commits intoflutter:masterfrom tvolkert:async
Conversation
|
@goderbauer I made the changes we discussed:
I don't love it, because Then again, I think the existing API is broken, so.... wdyt? |
goderbauer
left a comment
There was a problem hiding this comment.
It is sad that we lose the similarity to the Stream/StreamBuilder API. In the interest of a clean API, maybe we should just do the full-on breaking change under the existing data name?
|
Ok, @goderbauer I made the changes as discussed and sent out the breaking change announcement. PTAL. |
|
(PR triage): This will need some changes to address the concerns raised in #34545. |
|
Ok, updates per the conversation in #34545 have all been made. This is ready for another review. /cc @rrousselGit |
There was a problem hiding this comment.
should it be [_data] as it refers to parameter here?
There was a problem hiding this comment.
No, I'm linking to the property intentionally.
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#dartdoc-specific-requirements
There was a problem hiding this comment.
pity we can't preserve the stack trace
There was a problem hiding this comment.
maybe add a TODO pointing at dart-lang/sdk#30741.
There was a problem hiding this comment.
hasData is a bool, so that will be confusing. maybe ${hasData ? "has data" : "no data"} ?
There was a problem hiding this comment.
also, probably omit $_data if there's no data, and omit error if there's no error? in general this could be clearer in various ways.
There was a problem hiding this comment.
should use runtimeType not is
There was a problem hiding this comment.
docs should talk about what to do if you don't have the initial data (the common case)
There was a problem hiding this comment.
It's possible the stream will have produced data by the first frame. The docs above specifically call out that since the builder is called at the discretion of the Flutter pipeline, callers are not guaranteed to see every snapshot in rendered frames.
There was a problem hiding this comment.
can we have a more useful error message?
There was a problem hiding this comment.
Would it be more appropriate to use FlutterError here, or is StateError better? The docs on FlutterError say "Error class used to report Flutter-specific assertion failures and contract violations," but it's not clear to me from that description if widget implementations are encouraged to throw FlutterError or not.
There was a problem hiding this comment.
it's weird that we special-case void, though I guess it's understandable.
There was a problem hiding this comment.
we should definitely document this though
There was a problem hiding this comment.
I already do - see the docs lines starting with "The StreamBuilder<void> and StreamBuilder<Null> types will produce"
There was a problem hiding this comment.
we should make it clearer that _calculation must not be created during the call to the build method that creates the FutureBuilder.
There was a problem hiding this comment.
isn't this the common case? or even the only case, usually? seems weird to make this harder to use.
There was a problem hiding this comment.
i wouldn't accept Null here. If it's a Future<Null> and it completes (with null) then I do have data: null.
|
@Hixie all comments addressed - PTAL |
This updates `AsyncSnapshot.data` to act as `AsyncSnapshot.requireData` used to -- and it removes `AsyncSnapshot.requireData`. #34545 https://groups.google.com/forum/#!topic/flutter-announce/H6Od0QdsdrI
| this.future, | ||
| this.initialData, | ||
| @Deprecated( | ||
| "Don't provide initialData to FutureBuilder. Instead, check for " |
There was a problem hiding this comment.
we generally would phrase this more softly as "Instead of providing initialData to a FutureBuilder, consider checking for..."
| /// error itself will be available in [AsyncSnapshot.error], and | ||
| /// [AsyncSnapshot.hasError] will be true.) | ||
| @Deprecated( | ||
| "Don't use FutureBuilder.initialData. Instead, check for " |
| "Don't use FutureBuilder.initialData. Instead, check for " | ||
| 'ConnectionState.none or ConnectionState.waiting in your build() ' | ||
| 'method to know whether the future has completed or not.', | ||
| ) |
There was a problem hiding this comment.
deprecation explanation should be in /// dartdocs too
|
Mentions of LGTM. |
|
Is there a documentation for the I guess I will be answering some questions on StackOverflow soon 🤷 Edit: Instead, I prepared some questions and referred to the announcement. |
|
@creativecreatorormaybenot I also added a section to the changelog that covers the changes as well, with examples. https://github.com/flutter/flutter/wiki/Changelog#v183 |
|
@tvolkert Awesome, that's what I was missing previously. |
|
What's the migration plan for a package that needs to work both on Flutter master and stable, and is broken by this change? |
|
I actually just sent out #36577, which would swap the semantics of the two |
|
Won't that shift the problem(of not being able to work on both master and stable) to packages that provide initialData? |
|
take that back - I thought that PR removed |
@amirh there's still discussion in #34545 (comment) that could mean we don't merge #36577. If that ends up being the best course of action, then the migration plan for packages that need to work on both master and stable is to have them explicitly pass |
This updates `AsyncSnapshot.data` to act as `AsyncSnapshot.requireData` used to -- and it removes `AsyncSnapshot.requireData`. Correspondingly, this adds a `StreamBuilder.withoutInitialData()` constructor, makes the `initialData` argument to the default `StreamBuilder()` constructor required, and deprecates the `initialData` argument to the `FutureBuilder()` constructor. See the breaking change announcement for more info. flutter#34545 https://groups.google.com/forum/#!topic/flutter-announce/H6Od0QdsdrI
…" (flutter#36618) This reverts commit b61fcfd.
Description
Currently, if you attempt to access the
AsyncSnapshot.dataproperty when the error property is non-null, it will return null. This API often confuses users, who expect the property to throw an error if the error property is set.This change updates the API to throw an error if
erroris set -- and to correspondingly remove therequireDataproperty.After receiving this update, callers should update their code accordingly:
dataproperty without first checkinghasDataorhasError, they should update their code to checkhasDataorhasError, or to wrap theirdataaccess in a try/catch.requireDataproperty, they should update their code to simply access thedataproperty instead.Related Issues
#34545
Checklist
///).flutter analyze --flutter-repo) does not report any problems on my PR.Breaking Change
Does your PR require Flutter developers to manually update their apps to accommodate your change?