Clarify assertion failure for incorrect send usage (#151)

* Clarify assertion failure for incorrect send usage

* Update ViewStore.swift

* Update Sources/ComposableArchitecture/Store.swift

Co-authored-by: Dante Broggi <34220985+Dante-Broggi@users.noreply.github.com>

* Update Sources/ComposableArchitecture/Store.swift

Co-authored-by: Stephen Celis <stephen@stephencelis.com>

Co-authored-by: Dante Broggi <34220985+Dante-Broggi@users.noreply.github.com>
Co-authored-by: Stephen Celis <stephen@stephencelis.com>
This commit is contained in:
Brandon Williams
2020-05-29 09:30:56 -07:00
committed by GitHub
parent a20b0b1d6a
commit f25878c01f
2 changed files with 13 additions and 1 deletions

View File

@@ -139,10 +139,18 @@ public final class Store<State, Action> {
if self.isSending {
assertionFailure(
"""
The store was sent an action recursively. This can occur when you run an effect directly \
The store was sent an action while it was already processing another action. This can \
happen for a few reasons:
* The store was sent an action recursively. This can occur when you run an effect directly \
in the reducer, rather than returning it from the reducer. Check the stack (⌘7) to find \
frames corresponding to one of your reducers. That code should be refactored to not invoke \
the effect directly.
* The store has been sent actions from multiple threads. The `send` method is not \
thread-safe, and should only ever be used from a single thread (typically the main thread).
Instead of calling `send` from multiple threads you should use effects to process expensive \
computations on background threads so that it can be fed back into the store.
"""
)
}

View File

@@ -78,6 +78,10 @@ public final class ViewStore<State, Action>: ObservableObject {
/// Sends an action to the store.
///
/// `ViewStore` is not thread safe and you should only send actions to it from the main thread.
/// If you are wanting to send actions on background threads due to the fact that the reducer
/// is performing computationally expensive work, then a better way to handle this is to wrap
/// that work in an `Effect` that is performed on a background thread so that the result can
/// be fed back into the store.
///
/// - Parameter action: An action.
public func send(_ action: Action) {