Kiddo
Kiddo

Reputation: 1175

Why axios .catch() catch javascript error in redux middleware?

I use axios as my client for ajax request in react redux application.

To handle async action, I use middleware that will :

  1. Recognize promise object
  2. Resolve the promise with then() if success OR catch() if fail
  3. Resolved promise will dispatch action corresponding to its success/fail action. For example, GET_TRANSACTIONS will dispatch GET_TRANSACTIONS_SUCCESS or GET_TRANSACTIONS_FAIL

The problem is, everytime the application gets an error (like access property of undefined), it will trigger the catch() handler in the async action middleware and dispatch the fail action, which is not related.

As the result, the javascript error is not displayed in console, so I don't know what actually happen with the application.

The dispatched fail action's payload is just an empty object. (it should be access property of undefined)

How can I make sure that .catch() only handle promise error, not the javascript error?

clientMiddleware.js

export const clientMiddleware = (client) => {
  return ({ dispatch, getState }) => {
    return next => action => {
      if (typeof action === 'function') {
        return action(dispatch, getState)
      }

      const { promise, types, ...rest } = action

      if (!promise) {
        return next(action)
      }

      const [REQUEST, SUCCESS, FAILURE] = types
      next({ ...rest, type: REQUEST })

      const actionPromise = promise(client)

      actionPromise
        .then((res) => next({ ...rest, payload: res, type: SUCCESS }))
        .catch((err) => next({ ...rest, payload: err, type: FAILURE }))

      return actionPromise
    }
  }
}

Upvotes: 0

Views: 694

Answers (1)

jonicious
jonicious

Reputation: 364

How can I make sure that .catch() only handle promise error, not the javascript error?

AFAIK there is not. We are experiencing the same issue in our applications. Errors are kind of swallowed. For debugging purposes, we use something like this:

Promise.prototype.nativeCatch = Promise.prototype.catch;
Promise.prototype.catch = function(handler) {
    return this.nativeCatch(function(error) {
        try {
            console.error(error.stack);
        }
        catch(error) {

        }
        handler(error);
    });
};

Upvotes: 0

Related Questions