Get axios Response object when error occurred with Redux Saga
Asked Answered
T

3

6

This is new for me and I try to figure out how to retrieve the request body when an error occurred with axios using yield generator (redux-saga)

Here is the piece of code I'm using:

function requestLogin(user: ILoginUserPayload) {
  const loginUrl = `${config.apiUrl}/auth/logIn`;
  return axios.post(loginUrl, user);
}

export default function* watchAuthAction(): IterableIterator<any> {
  while (true) {
    const { payload }: { payload: ILoginUserPayload} = yield take(TYPES.LOGIN_REQUEST);

    console.log(`Payload`, payload);
    try {
      const response = yield requestLogin(payload);
      console.log(`Response`, response);
    } catch (error) {
      // According to my debug, error.request contains all the axios info
      console.log(error.request.response);
      yield put({ type: TYPES.LOGIN_FAILURE, error: error.request.response.message });
    }
  }
}

I used VSCode to debug the error content and I found out it has the axios request information (I mean, I 'm 99% sure that axios throw an error and it comes here)

My body response looks like that:

{"message":"User doesn't exist","stack":"Error: User doesn't exist"}

So I try to get it with:

console.log(error.request.response.message);

But it doesn't work, maybe I forget something about axios...

Any idea?

Edit: I'm actually reading this part: https://github.com/axios/axios#handling-errors But I still can't reach my data :/

Telegraphone answered 22/7, 2018 at 10:17 Comment(0)
B
6

Your code seems to be about right, only difference for me is this:

try {
    const response = yield call(apiCall, action.payload)
      yield put({ type: successReducer, payload: response });
  } catch(error) {
    // Construct an error message
    let errorMessage = error.response.status + ":"+ error.response.statusText;
    yield put({ type: failReducer, payload: {  message : errorMessage }});
  }

So to me the difference seems to be that I access error.response.status instead of error.request.response.

Bisector answered 19/3, 2019 at 13:50 Comment(1)
Yes that right, for you information I replied about it (see the other answer ;))Telegraphone
T
0

So it's an axios error coming to the catch as I expected.

I just follow the documentation to get the data :)

here is the part:

axios.get('/user/12345')
  .catch(function (error) {
    if (error.response) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // The request was made but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

In my case I just need to get the message using:

error.response.data.message
Telegraphone answered 22/7, 2018 at 10:27 Comment(4)
But how do you get that in the saga? Do you need to return something specific from the catch method of axios? ... I tried to return anything possible and still get some weird object in the saga ...Hildick
@peshohristov did you find what was the problem? I am having the same issueMaintain
@Maintain - Yes, I got answer that helped me, but it was in the issue I opened in the redux-saga repo. github.com/redux-saga/redux-saga/issues/1730 Hope this will help you :)Hildick
Thx. For me the problem was with debugger. When debugging saga it shows source mapped code, while stack trace and scope are showing compiled code so even though the error was there I couldn't see it in the debugger. github.com/redux-saga/redux-saga/issues/1972Maintain
L
0

Dude, I spent hours on it.

Here is what worked for me:

console.log(error.response.data.message);

So, inside your error object, there is a response object and then you can access everything inside the data object.

try {
  const response = yield requestLogin(payload);
  console.log(`Response`, response);
} catch (error) { 
  yield put({ type: TYPES.LOGIN_FAILURE, error: error.response.data.message });
}

You can debug it inside catch like this:

catch (error) {
    console.log('erro:', error.response.data.message) 
  }  
Lobbyism answered 27/7, 2021 at 21:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.