redux-saga: Recommended way to handle all saga errors

I’ve been searching through the issues about how to handle saga errors and wondering if there’s any recommended way to catch uncaught saga exceptions without having to put try/catch inside every saga.

My use case is showing a modal whenever the app JS crashes so I don’t need to handle errors individually at all, just need to catch uncaught exceptions and issue some SET_APP_ERROR_STATE action that will trigger showing the modal.

I see 1.0 release is in beta which will completely rework error handling, so I’m not keen to add a lot of code in the interim before that, given I don’t need to address specific errors at all. More like a high level wrapper would be most useful.

Is there any progress w/ safe saga effect? Or any relevant issues/gists how to “roll my own”? Any help/input greatly appreciated. Thanks for the nice library 😃

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 20 (17 by maintainers)

Most upvoted comments

and keep in mind if error bubbles to root saga and you have onError called --> the whole saga tree is terminated, so either your dispatch is used only for changing redux store or your action handler should be run as spawn effect. Usually, I consider onError as a fatal situation and don’t use any redux semantic inside

I plan to release release candidate of v1 this week and on your place I would wait for it. I would use onError option to createSagaMiddleware to listen for all errors and show a modal from there (i.e. by dispatching a redux action there).

safe wrapper can be easily implemented in userland:

const safeCall = (saga, ...args) => call(function* () {
    try {
        return { err: false, result: yield call(saga, ...args) }
    } catch (err) {
        return { err: true, result: err }
    }
})
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

// ...
import { helloSaga } from './sagas'

const sagaMiddleware = createSagaMiddleware({
  onError: () => {
    store.dispatch({ type: 'SET_ERROR_STATE' })
  }
})

const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)

export default store

What I was looking for is the option to analyze the error and decide if it should blow up the entire app or not.

seems that we should add it in docs, if we don’t have such notices yet

Sorry, I’m still not following 100%! I’m using vanilla store creation similar to the below, from the tutorial:

import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

// ...
import { helloSaga } from './sagas'

const sagaMiddleware = createSagaMiddleware({
  onError: () => {
    // how to access dispatch at this point?
  }
})
export default createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)

Could you share a quick gist of accessing store from the outer scope?

technically u might be able to implement this with effectMiddlewares feature in v1, not something I would personally do in my app, but if you want it then I think it’s doable

You can easily built that on top of existing APIs. You just need to think about your system in explicit manner without hiding implementations in some global handlers implicitly.

Just built a generic request saga which you can use whenever you’d like to use fetch (or similar)

@restrry So basically there’s no “built in” mechanism for global error handling (which won’t terminate the whole saga tree)?

Example use case: if any network call results in 401 - redirect to login page