Hawkes
Hawkes

Reputation: 467

Async error propagation in sagas

I'm using redux-saga to initiate a third party service and I want to propagate the errors from the third party's callback to the saga so that I can dispatch proper actions from the saga. How can I do so?

In sagas:

export function * handleFetchProducts () {
  try {
    const products= yield call(getProducts)
    yield put(actions.fetchProductsSuccess(products))
  } catch (e) {
    yield put(actions.fetchProductsFailure(e))
  }
}

In getProducts:

export async function getProducts() {
  return new Promise((resolve, reject) => {
    const kc = new Service()
    return Service.initialize()
      .success((products) => {
        resolve(products)
      })
      .error(() => {
        reject(new Error('Couldn\'t fetch'))
      })
  }
}

I know that since the error is being thrown from inside a async callback, I can't catch it in the try/catch of the sagas. But, I just wanted to know what should be the proper way of handling this.

Please note that the Service module is built as-is and I can't change it's behavior.

Any help would be

Upvotes: 0

Views: 150

Answers (1)

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

You could promisify getProducts

export function getProducts() {
  return new Promise((resolve, reject) => {
    const kc = new Service()
    kc.initialize()
      .success(resolve)
      // this will be caught
      .error(() => reject(new Error('...')))
  })
}

Alternatively you could use cps effect

export getProducts(next) {
  new Service()
    .initialize()
    .success(products => next(null, products))
    .error(() => next(new Error('...')))
}

//and in handleFetchProducts 

try {
    const products= yield cps(getProducts)
    ...
}

Upvotes: 1

Related Questions