flutter
runtime_error
ai_generated
true
StateError: Bad state: Cannot add event while adding another event
ID: flutter/state-error-bloc-event-handler
88%Fix Rate
88%Confidence
1Evidence
2023-11-15First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| flutter 3.16 | active | — | — | — |
| flutter 3.22 | active | — | — | — |
| bloc 8.0.0 | active | — | — | — |
| flutter_bloc 8.1.0 | active | — | — | — |
Root Cause
Attempting to call bloc.add() from within an event handler of the same Bloc instance, causing a reentrant call.
generic中文
在同一个 Bloc 实例的事件处理程序中调用 bloc.add(),导致重入调用。
Official Documentation
https://bloclibrary.dev/#/coreconcepts?id=adding-eventsWorkarounds
-
90% success Use a separate isolate or schedule the new event outside the current handler using Future.microtask(() => bloc.add(Event())). This ensures the current event processing completes before the new event is added.
Use a separate isolate or schedule the new event outside the current handler using Future.microtask(() => bloc.add(Event())). This ensures the current event processing completes before the new event is added.
-
85% success Restructure the Bloc logic to combine both operations into a single event or use async gaps like await Future.delayed(Duration.zero) before calling bloc.add().
Restructure the Bloc logic to combine both operations into a single event or use async gaps like await Future.delayed(Duration.zero) before calling bloc.add().
中文步骤
使用单独的隔离或通过 Future.microtask(() => bloc.add(Event())) 在当前处理程序外部调度新事件。这确保当前事件处理完成后再添加新事件。
重构 Bloc 逻辑,将两个操作合并为一个事件,或在使用 bloc.add() 之前使用异步间隙,如 await Future.delayed(Duration.zero)。
Dead Ends
Common approaches that don't work:
-
Adding a short delay with Future.delayed before bloc.add()
85% fail
Delay does not prevent the reentrant call from the same synchronous context; the error still occurs if the logic is in the same event handler chain.
-
Wrapping bloc.add() in a try-catch block
75% fail
The StateError is thrown synchronously and cannot be caught inside the event handler because Bloc internally throws it before the catch block is reached.