web-dev-qa-db-ja.com

JavaScript Fetch APIから読み取り可能なエラー応答を取得する方法

私はフロントエンドでReactjs reduxに取り組んでおり、バックエンドとしてRails apiです。

だから今私はフェッチAPIメソッドでAPIを呼び出しますが、問題は私がネットワークタブの中に取得したもののような読みやすいエラーメッセージを取得できないことです

これは私の機能です

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));

            });


    }
}

しかし、エラーが発生したとき、ブラウザのネットワークタブを確認したときのように、読みやすい応答メッセージを取得する方法を理解できません

したがって、これはエラーが発生したときにネットワークタブから取得したものです。

enter image description here

私のコンソール

enter image description here

これは私の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

しかし、私はそれを自分の関数の中にどのように入れることができるかわかりません

ありがとう!

9

はい、やっとこれが解けたと思います。

テキストは応答オブジェクト内のpromise内に隠されているため、それを表示するにはpromiseのように処理する必要があります。

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);
    }
7
Martins Untals

あなたはこのようなことをする必要があると思います

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());
            return response.json();
        })
        .then(function(object){
          if (object.errors) {
            dispatch(update_errors(response));
            throw new Error(object.errors);
          } else {
            console.log("succeed json re");
            dispatch(update_user(json));
          }
        })
        .catch(function(error){
          this.setState({ error })
        })
       }
     }
0
Neeraj Kumar

まず、応答でjsonメソッドを呼び出す必要があります。

例:

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) 
    });

うまくいかなかった場合は、コンソールログをお知らせください。

0
Dhyey

あなたの答えに似ていますが、もう少し説明があります...私は最初に応答に問題がないかどうかをチェックし、次にresponse.text()からエラーを生成します。したがって、ネットワークエラー(okではない)は、テキストに変換されずに独自のエラーを生成します。次に、これらのエラーはダウンストリームcatchでキャッチされます。

これが私の解決策です-私はコアフェッチ関数をラッパー関数にプルしました:

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

次に、それを使用するときに、そのときに必要に応じて応答とエラーを処理する方法を定義します。

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