web-dev-qa-db-fra.com

Comment obtenir une réponse d'erreur lisible de javascript Fetch api?

Je travaille sur Reactjs redux sur le front-end et sur Rails api en tant que back-end.

Alors maintenant, j'appelle api avec la méthode d'extraction d'api mais le problème est que je ne peux pas obtenir un message d'erreur lisible comme ce que j'ai dans les onglets du réseau

c'est ma fonction

export function create_user(user,userInfoParams={}) {

    return function (dispatch) {
        dispatch(update_user(user));

        return fetch(deafaultUrl + '/v1/users/',
            {
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json'
                },
                method: "POST",
                body: JSON.stringify(userInfoParams)
            })
            .then(function(response) {
                console.log(response);
                console.log(response.body);
                console.log(response.message);
                console.log(response.errors);
                console.log(response.json());
                dispatch(update_errors(response));

                if (response.status >= 400) {
                    throw new Error("Bad response from server");
                }

            })
            .then(function(json){
                console.log("succeed json re");
                // We can dispatch many times!
                // Here, we update the app state with the results of the API call.

                dispatch(update_user(json));

            });


    }
}

Mais quand des erreurs se sont produites, je ne peux pas comprendre comment obtenir un message de réponse lisible comme je l’ai eu quand j’ai vérifié sur les onglets du réseau de mon navigateur.

C'est donc ce que j'ai reçu des onglets du réseau quand j'ai eu des erreurs.

 enter image description here

Ma console

 enter image description here

Ceci est mon code Rails

def create
    user = User.new(user_params)
    if user.save
      #UserMailer.account_activation(user).deliver_now
      render json: user, status: 201
    else
      render json: { errors: user.errors }, status: 422
    end
  end

Mais je ne peux pas savoir comment puis-je obtenir cela dans ma fonction

Merci!

6

ok, je pense que j'ai finalement craqué ça. 

le texte est caché à l'intérieur de la promesse dans l'objet de réponse, il doit donc être traité comme une promesse de le voir. 

fetch(bla)
    .then(res => {
      if(!res.ok) {
        res.text().then(text => throw Error(text))
       }
      else {
       return res.json();
     }    
    })
    .catch(err => {
       console.log('caught it!',err);
    }
4
Martins Untals

Vous devez d’abord appeler la méthode JSON sur votre réponse. 

Un exemple:

fetch(`${API_URL}`, {
        method: 'post',
        headers: {
           'Accept': 'application/json',
           'Content-Type': 'application/json'
        },
        body: JSON.stringify(userInfoParams)
    })
    .then((response) => response.json())
    .then((response) => console.log(response)) 
    .catch((err) => {
        console.log("error", err) 
    });

Faites-moi savoir le journal de la console si cela ne fonctionne pas pour vous. 

0
Dhyey

Semblable à votre réponse, mais avec un peu plus d'explications ... Je vérifie d'abord si la réponse est correcte, puis génère l'erreur à partir de response.text() uniquement dans les cas où la réponse est correcte. Ainsi, les erreurs de réseau (qui ne sont pas ok) généreraient toujours leur propre erreur sans être converties en texte. Ensuite, ces erreurs sont interceptées dans la variable catch en aval. 

Voici ma solution - j'ai intégré la fonction de récupération principale dans une fonction d'emballage: 

const fetchJSON = (...args) => {
  return fetch(...args)
    .then(res => {
      if(res.ok) {
        return res.json()
      }
      return res.text().then(text => {throw new Error(text)})
    })
}

Ensuite, lorsque je l'utilise, je définis comment gérer ma réponse et les erreurs selon les besoins à ce moment-là:

fetchJSON(url, options)
  .then((json) => {
    // do things with the response, like setting state:
    this.setState({ something: json })
  })
  .catch(error => {
    // do things with the error, like logging them:
    console.error(error)
  })
0
Sia