Provider: Inconsistent behavior between `debug` and `release` builds

Created on 26 Sep 2019  ยท  11Comments  ยท  Source: rrousselGit/provider

Original Topic - https://github.com/flutter/flutter/issues/41289#issuecomment-535274201

Long story short, while running app in debug build - everything works as it should. However, when running build in release - certain providers doesn't get updated.

I've created mini project to demonstrate this case.
https://github.com/zeromaro/flutter-provider-bug

Solution - place provider into Future.microtask... After doing that - it worked.

But I would love to understand, why there are differences between builds? If it's expected, better to warn already if any provider code is placed in initState it has to be put in Future.microtask otherwise something can go wrong.

invalid question

All 11 comments

I'm more surprised by the fact that your code works in development.

It shouldn't, and others get an exception.
See https://stackoverflow.com/questions/56359049/setting-provider-value-in-futurebuilder/56480917#56480917

Thanks for joining, @rrousselGit . I know, right?

I think it's related to listen flag. As if it's true it won't work for sure.
Anyways, I'd love if there could be some improvements made on this, because it could save literally days on debugging these type of issues. As losing consistency between builds is extremely frustrating. :)

There's no inconsistency here, what you're asking for already exists.
When I run your repo in debug mode, I get an exception:

 โ•โ•โ•ก EXCEPTION CAUGHT BY FOUNDATION LIBRARY โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
I/flutter (29245): The following assertion was thrown while dispatching notifications for HomeStore:
I/flutter (29245): setState() or markNeedsBuild() called during build.
I/flutter (29245): This ListenableProvider<HomeStore> widget cannot be marked as needing to build because the framework
I/flutter (29245): is already in the process of building widgets.  A widget can be marked as needing to be built during
I/flutter (29245): the build phase only if one of its ancestors is currently building. This exception is allowed
I/flutter (29245): because the framework builds parent widgets before children, which means a dirty descendant will
I/flutter (29245): always be built. Otherwise, the framework might not visit this widget during this build phase.
I/flutter (29245): The widget on which setState() or markNeedsBuild() was called was:
I/flutter (29245):   ListenableProvider<HomeStore>
I/flutter (29245): The widget which was currently being built when the offending call was made was:
I/flutter (29245):   _BodyBuilder
I/flutter (29245):
I/flutter (29245): When the exception was thrown, this was the stack:
I/flutter (29245): #0      Element.markNeedsBuild.<anonymous closure> 
package:flutter/โ€ฆ/widgets/framework.dart:3680
I/flutter (29245): #1      Element.markNeedsBuild 
package:flutter/โ€ฆ/widgets/framework.dart:3695
I/flutter (29245): #2      State.setState 
package:flutter/โ€ฆ/widgets/framework.dart:1161
I/flutter (29245): #3      _ListenableDelegateMixin.startListening.<anonymous closure> 
package:provider/src/listenable_provider.dart:186
I/flutter (29245): #4      ChangeNotifier.notifyListeners 
package:flutter/โ€ฆ/foundation/change_notifier.dart:206
I/flutter (29245): #5      HomeStore.loadingState= 
package:provider_release_bug/home_store.dart:12
I/flutter (29245): #6      HomeStore.updateText 
package:provider_release_bug/home_store.dart:16
I/flutter (29245): <asynchronous suspension>
I/flutter (29245): #7      _FirstPageState.initState 

Either you didn't see the exception, or there's an issue in your environment.

Exception is there, but what about allowing code even to run? Or highlighting code part in IDE that it might cause issues? I can receive exceptions from other parts therefore filter right one it's hard (what happened in my current scenario as I was assuming everything comes from expected exceptions).

Debugging in Flutter is still way far of being good. I'd just love to have these silly mistakes exposed earlier to developer :)

I hope you get my point. And again, really appreciate your feedback on this.

I do not understand, no.
As you said, you already have an exception. What else do you need? ๐Ÿ˜ƒ

I would love that code wouldn't even run, because it's 100% will fail :) That's ideal case. Main goal is to save dev's time on debugging so why to even allow for code to run if it's already known that this kind of piece of code will fail. Just a suggestion. And note for myself to keep an eye on logs I suppose.

Sorry, I came from Android dev. background so for me it'd be very natural.

Cheers

What do you mean by "the code doesn't even run"?
It's an exception. It stops the execution

I mean that code runs perfectly fine on either debug and release builds. As you experienced yourself. And on debug it produces misleading behavior (Widget tree shouldn't get updated. However it gets updated).

Once code didn't run in release build - it becomes mystery why is that.

All I mean is debug and release builds should not influence behavior of the code. It's already used to be nightmare with ProGuard. As it becomes really hard to debug otherwise.

Oh, I finally understand the issue.
provider cannot do anything about it though. It's a problem with ChangeNotifier, not provider

I'll close this issue and report it to Flutter properly. I can't do anything about it.

@rrousselGit Thanks for looking into this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stocksp picture stocksp  ยท  5Comments

rrousselGit picture rrousselGit  ยท  3Comments

FaizanKamal7 picture FaizanKamal7  ยท  6Comments

ykaito21 picture ykaito21  ยท  3Comments

dikir picture dikir  ยท  5Comments