How to handle axios error in redux-saga in try catch

Martin l.k
2 min readOct 2, 2021

Recently, the issue of the redux-saga try catch troubled me. After some research, I finally found the issue and fixed the problem. In this blog I will detail the solution. If you encounter the same issue, hopefully this blog can save you some time.

The problem

My original code is as following:

I have a fetch function in my /services/Api.js:

import axios from axios;export const myFetch = async () => {
try{
const url = https://www.7timer.info/bin/astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0;
return await axios.get(url);
}catch(err){
throw new Error(err.message);
}
}

And then in my /redux/Saga.js:

import { call, put, takeLatest } from 'redux-saga/effects';
import { myFetch } from '../services/Api.js'
export function* myFetchSaga() {
try{
const { data } = yield call(myFetch);
yield put(myFetchSuccess(data);
}catch(err){
console.log(err);
}
}

My issue was the err object in the catch block in the Saga.js did not have the expected error message from my backend. Instead, it always has the empty string ‘’. When I directly throw the err object, I got the err in saga from my console log:

Error: Request failed with status code 401
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:60)

How should I get the error message in my saga try catch block ?

I then read the redux-saga’s official document about the error handling https://redux-saga.js.org/docs/basics/ErrorHandling. I realised that I don’t have to use try catch block in saga!

Here I modified my code and then I solved the issue:

updated /services/Api.js: ( I directly return the error.response )

import axios from axios;export const myFetch = async () => {
try{
const url = https://www.7timer.info/bin/astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0;
return await axios.get(url);
}catch({response}){
return response;
}
}

Updated /redux/Saga.js:

import { call, put, takeLatest } from 'redux-saga/effects';
import { myFetch } from '../services/Api.js'
export function* myFetchSaga() {
const { data, statusCode } = yield call(myFetch);
// I have only 4xx and 5xx http errors
if(statusCode >=400 && statusCode < 600){
console.log(data.message);
}else{
yield put(myFetchSuccess(data);
}
}

Conclusion

Because the saga is using javascript generator, the behavior inside saga behaves different to the normal javascript. The key is to avoid using try catch block in the saga, and do all the try catch in the http service layer. Hope this can help you, and let me know if you have better solution, enjoy coding : )

--

--

Martin l.k

Full-stack developer, project owner of node-ecommerce, react-ecommerce, react-backoffice and react-openapi