簡體   English   中英

如何從 javascript Fetch api 獲取可讀錯誤響應?

[英]How to get Readable error response from javascript Fetch api?

我正在前端使用 Reactjs redux,后端使用 Rails api。

所以現在我用 Fetch 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));

            });


    }
}

但是當錯誤出現時,我無法弄清楚如何獲得可讀的響應消息,就像我檢查瀏覽器網絡選項卡時得到的一樣

所以這就是我在出現錯誤時從網絡選項卡中得到的信息。

在此處輸入圖片說明

我的控制台

在此處輸入圖片說明

這是我的導軌代碼

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

但我不知道如何在我的函數中得到它

謝謝!

好吧,我想我終於破解了這個。

文本隱藏在響應對象內的承諾中,因此需要像承諾一樣處理它才能看到它。

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

與您的答案類似,但有更多解釋...我首先檢查響應是否正常,然后僅針對我們成功響應的情況從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)
  })

即使這是一個有點老的問題,我還是要插話。

在上面的評論中有這個答案:

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

當然,您可以使用它,但要記住一件重要的事情。 如果您從其余 api 返回 json 看起來為{error: 'Something went wrong'} return res.text().then(text => {throw new Error(text)}) {error: 'Something went wrong'} ,則上面顯示的代碼return res.text().then(text => {throw new Error(text)})肯定會起作用,但是res.text()實際上返回字符串。 是的,你猜對了! 字符串不僅會包含值,還會包含合並在一起的鍵! 這讓您別無選擇,只能以某種方式將其分開。 糟糕!

因此,我提出了一個不同的解決方案。

fetch(`backend.com/login`, {
   method: 'POST',
   body: JSON.stringify({ email, password })
 })
 .then(response => {
   if (response.ok) return response.json();
   return response.json().then(response => {throw new Error(response.error)})
 })
 .then(response => { ...someAdditional code })
 .catch(error => reject(error.message))

因此,讓我們打破代碼,第一then尤其如此。

.then(response => {
       if (response.ok) return response.json();
       return response.json().then(response => {throw new Error(response.error)})
})

如果響應沒問題(即服務器返回 2xx 響應),它返回另一個 promise response.json() ,隨后在下一個then塊中進行處理。

否則,我將再次調用response.json()方法,但也會為其提供自己的then代碼塊。 在那里我會拋出一個新的錯誤。 在這種情況下,括號中的響應throw new Error(response.error)是一個標准的 javascript 對象,因此我將從它那里獲取錯誤。

如您所見,最后還有catch代碼塊,您可以在其中處理新拋出的錯誤。 error.message <-- error 是一個由許多字段組成的對象,例如 name 或 message。我在這個特定實例中沒有使用 name。無論如何你一定有這個知識)

多啊! 希望有幫助!

我一直在尋找這個問題並遇到了這篇文章,所以我認為我的回答將來會對某人有所幫助。

度過美好的一天!

馬立克

我認為你需要做這樣的事情

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

您可以通過以下方式訪問錯誤消息:

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

            })
            // here's the way to access the error message
            .catch(function(error) {
              console.log(error.response.data.message)
            })

;

自述文件:您需要將catch()塊添加到您的代碼中。 這是基於您的函數的示例。 或者您需要逐個對象控制台日志對象,讓我們先說您console.log(error.response)並查看其中的嵌套對象是什么。 如果您只執行console.log(error)而沒有.response您將看不到錯誤的詳細對象,請注意這一點。 在某些情況下,它是這樣的:[1]: https : console.log(error.response) (這張圖片顯示在你執行console.log(error.response)之后你看到了什么對象結構。

所以你需要去error.response.data並執行console.log直到你找到你想要的信息。

這些是基於上述問題在末尾添加 catch() 塊的代碼:

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");
            dispatch(update_user(json));
        
        .catch(
            (error) => {
               console.log(error.response.data.status.message)  //Here is the solution
        }
      );
   );
}}

希望這會有所幫助,如果您仍然遇到任何問題,請在評論中告訴我。

返回的變量不在response.bodyresponse.message

您需要檢查響應對象上的錯誤屬性。

if(response.errors) {
    console.error(response.errors)
}

在此處查看https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

您實際上應該從服務器返回錯誤響應代碼並使用 fetch API 的.catch()函數

首先,您需要在響應中調用 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) 
    });

如果它對您不起作用,請告訴我控制台日志。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM