Error handling on action payload
sombreroEnPuntas opened this issue · 2 comments
I'm following the docs to implement redux-actions
in a project.
https://redux-actions.js.org/api/createaction#createactiontype
When I get to the error handling example:
const noop = createAction('NOOP');
const error = new TypeError('not a number');
expect(noop(error)).to.deep.equal({
type: 'NOOP',
payload: error,
error: true
});
I noticed that when I pass an error for testing, like this:
const {
successAction,
errorAction
} = createActions({
SUCCEESS_ACTION: payload => ({
data: payload
}),
ERROR_ACTION: payload => ({
error: payload
}),
});
try {
let data;
// ... some stuff to fetch data :)
throw Error('Bad times on the internetz');
successAction(data);
} catch (error) {
errorAction(error):
}
The action is now:
{
type: 'ERROR_ACTION',
payload: {}, // Expected it to be 'Error: Bad times on the internetz' instance
error: true
}
Did I write a wrong implementation? What should be the right way to get the error?
I want to be able to reduce the action with an error payload and save the error to the store for further steps (like showing a toast with the error message to the user)
:(
Flux Standard Actions, which redux-actions
providers helpers for, represent success and error "versions" of an action as the same action type. createAction()
will create action-creator functions which accept either a value or an error object. When the code which may have success or error paths needs to dispatch an action, you can use the same action creator.
// action creators.js
const readDataCompleted = createAction('DATA/READ_COMPLETED`)
// getdata.js
import somethingHappened from './actions'
import store from './store'
try {
const response = await fetch('some_url')
if(!response.ok) throw new Error('Bad times on the internetz.')
const body = await response.json()
store.dispatch(somethingHappened(body))
}
catch (err) {
store.dispatch(somethingHappened(err))
}
Code similar to this will produce a "success" action when following the happy path:
{
type: 'DATA/READ_COMPLETED',
payload: /* ... your data ... */
}
... and an 'error' action when following the error path:
{
type: 'DATA/READ_COMPLETED',
error: { message: 'Bad times on the internetz.' }
}
// well, it'll be a proper error object, not the pseudo-error object I wrote above.
This means that your reducers need to contain logic for handling the success and error states. You can roll your own, or use handleAction()/handleActions()
, also included in the redux-actions library, to help create these "error aware" reducers. I'll leave you to look at the docs for handleAction()
.