Skip to content

Dispatch failure FSA when fetch fails #175

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

Merged
merged 2 commits into from
Jun 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,8 @@ The `[RSAA].types` property controls the output of `redux-api-middleware`. The s
- `fetch` may throw an error: the RSAA definition is not strong enough to preclude that from happening (you may, for example, send in a `[RSAA].body` that is not valid according to the fetch specification — mind the SHOULDs in the [RSAA definition](#redux-standard-api-calling-actions));
- a network failure occurs (the network is unreachable, the server responds with an error,...).

If such an error occurs, a different *request* FSA will be dispatched (*instead* of the one described above). It will contain the following properties:
- `type`: the string constant in the first position of the `[RSAA].types` array;
If such an error occurs, a *failure* FSA will be dispatched containing the following properties:
- `type`: the string constant in the last position of the `[RSAA].types` array;
- `payload`: a [`RequestError`](#requesterror) object containing an error message;
- `error: true`.

Expand Down Expand Up @@ -666,6 +666,7 @@ For example, if you want the status code and status message of a unsuccessful AP
}
}
```

By default, *failure* FSAs will not contain a `meta` property, while their `payload` property will be evaluated from
```js
(action, state, res) =>
Expand All @@ -674,6 +675,9 @@ By default, *failure* FSAs will not contain a `meta` property, while their `payl
)
```


Note that *failure* FSAs dispatched due to fetch errors will not have a `res` argument into `meta` or `payload`. The `res` parameter will exist for completed requests that have resulted in errors, but not for failed requests.

### Exports

The following objects are exported by `redux-api-middleware`.
Expand Down Expand Up @@ -898,6 +902,9 @@ $ npm install && npm test
## Upgrading from v2.0.x

- The `CALL_API` alias has been removed
- Error handling around failed fetches has been updated (#175)
- Previously, a failed `fetch` would dispatch a `REQUEST` FSA followed by another `REQUEST` FSA with an error flag
- Now, a failed `fetch` will dispatch a `REQUEST` FSA followed by a `FAILURE` FSA

## License

Expand Down
2 changes: 1 addition & 1 deletion src/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function apiMiddleware({ getState }) {
return next(
await actionWith(
{
...requestType,
...failureType,
Copy link
Contributor

@darthrellimnad darthrellimnad Apr 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a "migration" helper option could exist? like:

   ...(options.legacyRequestError ? requestType : failureType),

maybe until v4 or something, although not sure if anyone else might find this useful, can always stick with v2 till you're ready for migration too :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to a migration helper, but I don't know what the right approach is here. A breaking change that:

  • requires you to go in and add a legacyRequestError: true to your RSAAs as a temporary fix

OR

  • requires you to update your error handling paths to this new spec

I lean towards the latter but can be convinced otherwise!

payload: new RequestError(e.message),
error: true
},
Expand Down
41 changes: 19 additions & 22 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,7 @@ test('apiMiddleware must dispatch an error request FSA when [RSAA].options fails
actionHandler(anAction);
});

test('apiMiddleware must dispatch an error request FSA on a request error', t => {
test('apiMiddleware must dispatch an failure FSA with an error on a request error', t => {
const anAction = {
[RSAA]: {
endpoint: 'http://127.0.0.1/api/users/1', // We haven't mocked this
Expand All @@ -1192,7 +1192,9 @@ test('apiMiddleware must dispatch an error request FSA on a request error', t =>
const doNext = action => {
switch (action.type) {
case 'REQUEST':
if (!action.error) {
if (action.error) {
t.fail('Request FSA should not have an error');
} else {
t.pass('next handler called');
t.equal(
action.type,
Expand All @@ -1213,31 +1215,26 @@ test('apiMiddleware must dispatch an error request FSA on a request error', t =>
action.error,
'dispatched non-error FSA has correct error property'
);
break;
} else {
t.pass('next handler called');
t.equal(
action.type,
'REQUEST',
'dispatched error FSA has correct type property'
);
t.equal(
action.payload.name,
'RequestError',
'dispatched error FSA has correct payload property'
);
t.equal(
action.meta,
'someMeta',
'dispatched error FSA has correct meta property'
);
t.ok(action.error, 'dispatched error FSA has correct error property');
}
break;
case 'FAILURE':
t.equal(
action.type,
'FAILURE',
'dispatched error FSA has correct type property'
);
t.equal(
action.payload.name,
'RequestError',
'dispatched error FSA has correct payload property'
);
t.ok(action.error, 'dispatched error FSA has correct error property');
break;
}
};
const actionHandler = nextHandler(doNext);

t.plan(10);
t.plan(8);
actionHandler(anAction);
});

Expand Down