Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在React表单提交处理程序中正确捕获和分析错误?_Javascript_Reactjs_Error Handling_Fetch Api - Fatal编程技术网

Javascript 如何在React表单提交处理程序中正确捕获和分析错误?

Javascript 如何在React表单提交处理程序中正确捕获和分析错误?,javascript,reactjs,error-handling,fetch-api,Javascript,Reactjs,Error Handling,Fetch Api,我使用的是React 16.13.0。我有以下功能来处理提交事件: handleFormSubmit(e) { e.preventDefault(); const NC = this.state.newCoop; delete NC.address.country; fetch('/coops/',{ method: "POST", body: JSON.stringify(this.state.newCoop), headers: {

我使用的是React 16.13.0。我有以下功能来处理提交事件:

handleFormSubmit(e) {
  e.preventDefault();
  const NC = this.state.newCoop;
  delete NC.address.country;

  fetch('/coops/',{
      method: "POST",
      body: JSON.stringify(this.state.newCoop),
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
  }).then(response => {
      if (response.ok) {
          return response.json();
      }
      console.log(response.json());
      console.log(response.body);
      throw new Error(response.statusText);
  }).catch(errors => {
      console.log(errors);
      this.setState({ errors });
  });
}
但是,我在从响应中正确获取错误时遇到了一个问题。当发生错误时,我的端点返回一个包含错误文本的400请求。这就是curl中发生的情况:

curl --header "Content-type: application/json" --data "$req" --request POST "http://localhost:9090/coops/"
{"phone":["The phone number entered is not valid."]}
但是
response.statusText
包含“400(错误请求)”。捕获错误文本并将其保留以供将来解析的正确方法是什么?如果我的端点需要以不同的方式格式化数据,它应该做什么(使用Django/Python3.7)

编辑:

这是我试图在其中显示错误的输入组件:

<Input inputType={'text'}
    title = {'Phone'}
    name = {'phone'}
    value = {this.state.newCoop.phone}
    placeholder = {'Enter phone number'}
    handleChange = {this.handleInput}
    errors = {this.state.errors}
/> 
当我运行
console.log(错误)
时,它们如下所示:

{phone: Array(1), web_site: Array(1)}

实际上,
fetch
API与其他API有些不同。您应该传递另一个
.then()
来获取数据,然后对其进行分析,使用几个回调使代码难以读取,我使用
async/await
来处理错误:

async handleFormSubmit(e) {
  e.preventDefault();
  const NC = this.state.newCoop;
  delete NC.address.country;

  try {
    const response = await fetch('/coops/',{
      method: "POST",
      body: JSON.stringify(this.state.newCoop),
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
      },
    });

    if (response.ok) {
      const result = await response.json();
      console.log('_result_: ', result);
      return result;
    }

    throw await response.json();

  } catch (errors) {

    console.log('_error_: ', errors);
    this.setState({ errors });
  }
}
更新您的新问题: 当然,这是另一个问题,为什么错误没有出现,事实上,
电话
错误是和JavaScript数组,您应该通过下面的方式显示它,代码,我使用重构分配作为道具:

import React from 'react';
import { FormControl, FormLabel } from 'react-bootstrap';

const Input = ({
  title,
  type,
  name,
  value,
  placeholder,
  handleChange,
  errors,
}) => (
  <div className="form-group">
    <FormLabel>{title}</FormLabel>
    <FormControl
      type={type}
      id={name}
      name={name}
      value={value}
      placeholder={placeholder}
      onChange={handleChange}
    />
    {errors && errors[name] && (
      <FormControl.Feedback>
        {errors[name].map((err, i) => (
          <div key={err+i} className="fieldError">{err}</div>
        ))}
      </FormControl.Feedback>
    )}
  </div>
);

export default Input;

从“React”导入React;
从“react bootstrap”导入{FormControl,FormLabel};
常量输入=({
标题
类型,
名称
价值
占位符,
handleChange,
错误,
}) => (
{title}
{errors&&errors[name]&&(
{errors[name].map((err,i)=>(
{err}
))}
)}
);
导出默认输入;

您并没有真正解释如何处理响应。但是根据您对
抛出新错误的使用情况,我假设您需要以下
.catch
调用来处理它。在下面的解决方案中,
errors
将从JSON响应中分配对象

response.json()
返回承诺。如果要将该值作为错误“抛出”,则必须执行以下操作(而不是
抛出新错误(…)
):

回调返回被拒绝的承诺。然后
回调将导致所述
调用返回的承诺也被拒绝

在这方面:

 fetch('/coops/',{
        method: "POST",
        body: JSON.stringify(this.state.newCoop),
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
    }).then(response => {
        if (response.ok) {
            return response.json();
        }
        return response.json().then(x => Promise.reject(x));
    }).catch(errors => {
        console.log(errors);
        this.setState({ errors });
    });
注意:由于您没有使用成功响应的返回值执行任何操作,因此不需要使用
if
语句中的
return response.json()
。您可以将该调用重写为:

.then(response => {
  if (!response.ok) {
    return response.json().then(x => Promise.reject(x));
  }
})
如果我的端点需要以不同的方式格式化数据,它应该做什么(使用Django/Python3.7)

由于我们不知道您的组件需要什么样的结构,因此我们无法提供太多建议

属性API声明:

只读

一个布尔值,指示响应是否成功(状态为 范围为200–299)

这意味着即使
response.ok
为false,
response.json()
也将返回数据

获取一个流并将其读取到完成。它返回一个 使用解析正文文本的结果解析为

因此,在代码中,您应该将第一次获取解析定义为异步,如果响应不是
ok
,则使用
wait
,使用解析的
response.json()
抛出

handleFormSubmit(e){
e、 预防默认值();
const NC=this.state.newCoop;
删除NC.address.country;
获取(“/coops/”{
方法:“张贴”,
正文:JSON.stringify(this.state.newCoop),
标题:{
“接受”:“应用程序/json”,
“内容类型”:“应用程序/json”
},
}).then(async response=>{//定义异步函数的第一个解析
if(response.ok){
//如果可以,解析JSON并返回实际数据
return wait response.json();
//或者最好设置反应状态
//const data=wait response.json();
//this.setState({data});
}否则{
//不正常,在JSON数据中抛出一个错误
//这样你就能抓住
抛出wait response.json();
}
}).catch(错误=>{
//这里您应该得到JSON响应的实际错误
console.log(错误);
this.setState({errors});
});
}
您可以在此检查正在使用的测试示例

如果我的端点需要以不同的方式格式化数据,它应该做什么 (使用Django/Python 3.7)

您必须通过提供一些代码和解释,让我们更多地了解端点如何处理请求

更新

关于组件和显示错误,结果JSON为每个字段返回一个错误数组。如果只显示一个错误,则将端点更改为返回字符串而不是数组,或者仅显示第一个错误。如果有多个错误,则可以通过每个字段的“所有错误”数组进行映射和渲染:

const输入=(道具)=>{
返回(
{props.title}
//如果只想显示第一个错误
//然后渲染errors数组的第一个元素
{props.errors&&props.errors[props.name]&&(
{props.errors[props.name][0]}
)}
//或者如果每个字段都有多个错误
//然后映射并渲染所有错误
{/*
{props.errors&&props.errors[props.name]&&(
{props.errors[props.name].map((错误,索引)=>(
{错误}
))}
)}
*/}
)
}

让catch部分捕获失败错误,然后在then部分捕获您需要的错误

  }).then(response => {
       //use a switch to got through the responses or an if statement 
        var response = JSON.Parse(response)
        //here am assuming after you console log response you gt the correct array placement
        if(response[0]==200){
           // this indicates success
              return  JSON.stringify({"success":"true","message":"success message";})
         }else if(response[0]==400){
           // this indicates error
              return  JSON.stringify({"success":"false","message":"Error message";})
           }
  }).catch(errors => {
      console.log(errors);
      this.setState({ errors });
  });
另一方面,您可以检查数组中的第一个条目,以确定查询是否成功
.then(response => {
  if (!response.ok) {
    return response.json().then(x => Promise.reject(x));
  }
})
  }).then(response => {
       //use a switch to got through the responses or an if statement 
        var response = JSON.Parse(response)
        //here am assuming after you console log response you gt the correct array placement
        if(response[0]==200){
           // this indicates success
              return  JSON.stringify({"success":"true","message":"success message";})
         }else if(response[0]==400){
           // this indicates error
              return  JSON.stringify({"success":"false","message":"Error message";})
           }
  }).catch(errors => {
      console.log(errors);
      this.setState({ errors });
  });