About Generator and Error
Error happens, with or without a Generator.
It's best to have no Errors at all, but if there is,
better handle them within ServiceGenerator.
A Recommended approach is yield res(action) or store.dispatch(action) an ErrorAction,
then process all of then in one place.
Error during Generator code running
The Error can be normally caught, like:
try {
dispatch({ type: 'service:action' })
} catch (error) {
// on reject logic
}
Though it's possible the Error may be caught by an Entry or another higher level middleware first.
"Generator is already running"
This is when generator.next() is called during another generator.next().
Check the Stack of the logged Error, you'll get patterns like:
TypeError: Generator is already running
at generator.next <--- again
...
at generator
at generator.next <--- once
...
Here's one way to get the Error:
function * testGeneratorFunction () {
let data = 2
while (data--) {
entryCounter()
console.log('yield begin', data)
console.log('yield end', yield data)
}
}
const testGenerator = testGeneratorFunction()
let entryCount = 0
function entryCounter (data) {
entryCount++
try {
console.log('[entryCounter] begin', entryCount)
console.log('[entryCounter] end', testGenerator.next(data))
} catch (error) {
console.warn('GOT ERROR', error, error.stack)
}
entryCount--
}
entryCounter('ShowError') // TypeError: Generator is already running
entryCounter('ShowError') // TypeError: Generator is already running
entryCounter('ShowError')
When using Redux-Service, this Error may pop when:
Using store.dispatch(action) in the Generator, instead of yield res(action)
and the Action (or any chained-up Action) is also requested by this Generator.
To prevent this Error from potentially happen, simply 'Prevent Loop in Service', do not write looped logic in the first place
Redux-Service will Skip and Block the re-entry Action, and reduce the Error down to a Warning Log, and thus this Error could not be caught
If there's no better option, the Generator re-entry can be avoided by:
- Use
yield res()to send potentially related Action - Use
setTimeout()along withstore.dispatch(action)