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)