I try to handle Unauthorized
error from server using redux-saga. This is my saga:
function* logIn(action) { try { const user = yield call(Api.logIn, action); yield put({type: types.LOG_IN_SUCCEEDED, user}); } catch (error) { yield put({type: types.LOG_IN_FAILED, error}); } }
I fetch data like this:
fetchUser(action) { const {username, password} = action.user; const body = {username, password}; return fetch(LOGIN_URL, { method, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(body) }) .then(res => { res.json().then(json => { if (res.status >= 200 && res.status < 300) { return json } else { throw res } }) }) .catch(error => {throw error}); }
But anyway result is {type: 'LOG_IN_SUCCEEDED', user: undefined}
when I expect {type: 'LOG_IN_FAILED', error: 'Unauthorized'}
. Where is my mistake? How to handle errors right using Redux-Saga?
Advertisement
Answer
Don’t handle the then
and error
in your fetchUser
method and your saga. Since you are already try
/catch
ing in your saga, you could handle it there.
Example
Saga
function* logIn(action) { try { const response = yield call(Api.logIn, action); if (response.status >= 200 && response.status < 300) { const user = yield response.json(); yield put({ type: types.LOG_IN_SUCCEEDED, user }); } else { throw response; } } catch (error) { yield put({ type: types.LOG_IN_FAILED, error }); } }
Fetch
fetchUser(action) { const { username, password } = action.user; const body = { username, password }; return fetch(LOGIN_URL, { method, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(body) }) }
As a side note: I find fetch
‘s api a little awkward because it returns a then
-able response when you make a request. There are many libraries out there; personally I prefer axios
which returns json by default.