Passing additional information to errors handled by `redux-actions`

160 Views Asked by At

redux-actions handles errors "automatically":

if the payload is an instance of an Error object, redux-actions will automatically set action.error to true

And the error will be the payload of this action.

But if the payload is made of the error, how can I extract information from this action in my reducer to mark the related item as "on error" (except by extracting information from the error message) ?

import { createAction } from 'redux-actions'
import * as api from '../api'

export const fetchSomethingRequest = createAction('FETCH_SOMETHING_REQUEST')
export const fetchSomethingResponse = createAction('FETCH_SOMETHING_RESPONSE')

export const fetchSomething = id => dispatch => {
  dispatch(fetchSomethingRequest({ id }))

  return api
    .fetchSomething(id)
    .then(something => dispatch(fetchSomethingResponse({ id, something })))
    // I would like to add some information to be able afterwards (eg. in a
    // reducer) to mark `id` as on error
    .catch(error => dispatch(fetchSomethingResponse(error)))
    // with regular actions, I would do something like this
    // .catch(error => dispatch(fetchSomethingResponse({ id, error }))) 
}

I guess I could use the meta information of the action, but I think there's something I'm missing here.

Note: Flux Standard Action thinks of errors as a first class concept:

Flux actions can be thought of as an asynchronous sequence of values. It is important for asynchronous sequences to deal with errors. Currently, many Flux implementations don't do this, and instead define separate action types like LOAD_SUCCESS and LOAD_FAILURE. This is less than ideal, because it overloads two separate concerns: disambiguating actions of a certain type from the "global" action sequence, and indicating whether or not an action represents an error. FSA treats errors as a first class concept.

1

There are 1 best solutions below

4
On

When you are passing an error to action creator, error object should be accessible via action.payload, while action.error is just a boolean flag which is signalizing that payload is error.

You also can inherit default Error to store additional data:

class MyError extends Error {
  constructor(message, payload) {
    super(message);
    this.payload = payload
  }
}