发送res.status(409).send('error')不起作用

时间:2019-09-01 05:21:29

标签: node.js reactjs

状态代码为200时,我的后端(节点js)正确地将数据发送到前端,但是状态代码不是200时,则不向前端发送任何东西

前端代码:

handleSubmit = async (e) => {
    try {
        e.preventDefault()
        const result = await createPost(JSON.parse(JSON.stringify(this.state)))
        console.log(result) // ==> if status code !== 200 => result=undefined 
        if (result.status === 200) toast.success('پست با موفقیت ساخته شد')

    } catch (ex) {
        console.log(ex)
        if (ex.response && ex.response.status === 400)
            toast.error('لطفا کلیه موارد را پر کنید');
    }
}

后端代码

router.post('/', auth, async (req, res) => {
    const { error } = validate(req.body);
    if (error) return res.status(400).send(error.details[0].message);

    let post = new Post({
        postTitle: req.body.postTitle,
        postImageUrl: req.body.postImageUrl,
        postContent: req.body.postContent,
        postTags: req.body.postTags
    });

    post = await post.save();

    res.status(200).send(post);
});

如果后端响应状态不是200,我希望运行catch部分, 但是当状态代码为400 ex.response和ex.response.status时未定义。

运行此命令时,我的控制台在浏览器中记录以下消息:

  

POST http://localhost:3800/api/post 400(错误请求)

     

createPost.jsx:19未定义

     

createPost.jsx:23 TypeError:无法读取以下属性的“状态”   未定义       在CreatePost.handleSubmit(createPost.jsx:20)

我的验证功能是:

const validate = post => {
    const schema = {
        postTitle: Joi.string().required(),
        postDate: Joi.string(),
        postImageUrl: Joi.string(),
        postContent: Joi.string().required(),
        postTags: Joi.array(),
        postLike: Joi.number()
    };

    return Joi.validate(post, schema);
};

我的创建帖子组件是:

import React, { Component } from 'react';
import { createPost } from '../../services/postService'
import { toast } from 'react-toastify';
import _ from 'lodash'

class CreatePost extends Component {
    state = {
        postTitle: '',
        postImageUrl: '',
        postContent: '',
        postTags: []
    }

    handleSubmit = async (e) => {
        try {
            e.preventDefault()

            const result = await createPost(JSON.parse(JSON.stringify(this.state)))
            console.log(result) // ==> if status code !== 200 => result=undefined 
            if (result.status === 200) toast.success('پست با موفقیت ساخته شد')

        } catch (ex) {
            console.log(ex)
            if (ex.response && ex.response.status === 400)
                toast.error('لطفا کلیه موارد را پر کنید');
        }
    }

    render() {
        return (
            <form
                className="form-group bg-light border rounded m-2 shadow p-5"
                onSubmit={this.handleSubmit}
            >
                <label className="col-md-4 control-label" htmlFor="txtTitle">
                    عنوان پست
                </label>
                <input
                    id="txtTitle"
                    name="postTitle"
                    type="text"
                    placeholder="عنوان"
                    className="form-control input-md m-2"
                    value={this.state.postTitle}
                    onChange={e => this.setState({ postTitle: e.target.value })}
                />

                <input
                    id="txtImageUrl"
                    name="postImageUrl"
                    type="text"
                    placeholder="لینک عکس (الزامی نیست)"
                    className="form-control input-md m-2"
                    value={this.state.postImageUrl}
                    onChange={e =>
                        this.setState({ postImageUrl: e.target.value })
                    }
                />

                <textarea
                    name="postContent"
                    className="form-control m-2"
                    rows="5"
                    placeholder="متن پست"
                    value={this.state.postContent}
                    onChange={e =>
                        this.setState({ postContent: e.target.value })
                    }
                />

                <label className="col-md-4 control-label" htmlFor="txtTags">
                    برچسب ها
                </label>

                <input
                    id="txtTags"
                    name="postTags"
                    type="text"
                    placeholder="برچسب را با (,) از هم جدا کنید"
                    className="form-control input-md m-2"
                    value={this.state.postTags}
                    onChange={e =>
                        this.setState({
                            postTags: _.split(e.target.value, ',')
                        })
                    }
                />

                <button className="btn btn-success m-5">ساخت پست جدید</button>
            </form>
        );
    }
}

export default CreatePost;

创建邮递服务是:

export function createPost(post) {
    return http.post(config.api_post, post)
}

和http服务是:     从'axios'导入axios     从“ react-toastify”导入{toast}

axios.defaults.headers.common['x-auth-token']=localStorage.getItem('token')

axios.interceptors.response.use(null, error => {
    const expectedError =
        error.response &&
        error.response.status >= 400 &&
        error.response.status < 500

    if (!expectedError){
        console.log('Logging the error:', error)
        toast.error('خطایی رخ داده است')

        return Promise.reject(error)        
    }
})

export default {
    get: axios.get,
    post: axios.post,
    put: axios.put,
    delete: axios.delete,
    patch: axios.patch
}

和github存储库是: https://github.com/mehdiparastar/personal-site.git

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

问题出在您的axios.interceptor上。如果您在4xxcatch,通常http try/catch的错误将进入await axios块。但是您已经拦截并更改了行为。

在您的拦截器逻辑中,expectedError的HTTP true错误的计算结果为4xx

const expectedError =
      error.response &&
      error.response.status >= 400 &&
      error.response.status < 500
// expectedError === true

此区块不会被撤消

if (!expectedError){
    console.log('Logging the error:', error)
    toast.error('خطایی رخ داده است')

    return Promise.reject(error)        
}

由于您没有else块且没有默认返回值,因此拦截器返回undefined块中处理的try(JS中的默认返回值),因为它是不是错误

因此错误不是来自catch块:

const result = await createPost(JSON.parse(JSON.stringify(this.state)))
// result is undefined
if (result.status === 200) // <-- error is from this line

因此,您可以简单地使用else块或默认的retrun,例如:

if (!expectedError){
    ...
    return Promise.reject(error)        
} else {
    return error // or Promise.resolve(error)
}

// OR

if (!expectedError){
    ...
    return Promise.reject(error)        
}

return error //etc