Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how can I setup a global error handler? #1672

Closed
howard-repos opened this issue Nov 13, 2018 · 8 comments
Closed

how can I setup a global error handler? #1672

howard-repos opened this issue Nov 13, 2018 · 8 comments

Comments

@howard-repos
Copy link

I knew that exception in call effect should be catched otherwise it will propagate to parent.But I do not want to wirte the same try/catch code everywhere, so can I setup a global error handler for these kind of things.

function* fetchProducts() {
  try {
    const products = yield call(Api.fetch, '/products')
    yield put({ type: 'PRODUCTS_RECEIVED', products })
  }
  catch(error) {
    yield put({ type: 'FAILED', error })
  }
}
@Taym95
Copy link

Taym95 commented Nov 13, 2018

Do you want to catch all uncaught exceptions? if yes you can do it like this:

const rootTask = sagaMiddleware.run(rootSaga); rootTask.done.catch(function (err) { console.log("Error in Sagas", err); });

@howard-repos
Copy link
Author

howard-repos commented Nov 13, 2018

Do you want to catch all uncaught exceptions? if yes you can do it like this:

const rootTask = sagaMiddleware.run(rootSaga); rootTask.done.catch(function (err) { console.log("Error in Sagas", err); });

But in this way, the rootTask has been stopped.

@howard-repos
Copy link
Author

Or how can I make the following code keep running even though there is an error in Api.fetch

export function* getAllProducts() {
  const products = yield call(api.getProducts)
  yield put(actions.receiveProducts(products))
}

export function* watchGetProducts() {
  yield takeEvery(actions.GET_ALL_PRODUCTS, getAllProducts)
}

@feichao93
Copy link
Member

@Kabike You could use the following code to let your saga automatically restart when it encounters an error:

function keepAlive(sagaFn) {
  return function*() {
    while (true) {
      try {
        const result = yield io.call(sagaFn)
        console.log('saga completes with result:', result)
        return result
      } catch (e) {
        console.error('saga aborted due to:', e)
        console.log('restarting the saga...')
      }
    }
  }
}

// And your code becomes like...
yield takeEvery(actions.GET_ALL_PRODUCTS, keepAlive(getAllProducts))

You can put keepAlive at a higher level (say, the rootSaga) to control the granularity of restarting behaviors.restart

@mshustov
Copy link
Contributor

mshustov commented Nov 22, 2018

root saga restart will reset internal state of it and its child sagas
another alternative is to write your safe call wrapper, which also could do reporting
#1250

@mshustov
Copy link
Contributor

closed as there are no action points here

@michael-freidgeim-webjet

We used function similar to suggested by @Taym95

    sagaMiddleware.run(rootSagas, store.dispatch).done.catch(e => {
        logger.error({ message: e.message, source: 'sagaError', stacktrace: e.sagaStack });
    });

with old version "redux-saga": "^0.15.3",, but after I tried to update to the latest V1.1.1,
I am getting TypeError: Cannot read property 'catch' of undefined.
What is correct syntax now?

@Andarist
Copy link
Member

Andarist commented Oct 8, 2019

sagaMiddleware.run(rootSagas, store.dispatch).toPromise().catch(e => {
        logger.error({ message: e.message, source: 'sagaError', stacktrace: e.sagaStack });
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants