简体   繁体   中英

Is there any problem in handling 'throw error' inside try-catch in async await?

I have a method for posting a product into mongodb using mongoose. I'm using async await instead of the then-catch block. My code:

const Category = require('../models/category');

exports.postProduct = async (req,res,next)=>{
    //const userId = req.user.userId;
    const userId = '5dca886a1ee97b07002de048';
    // const category = req.body.category;
    const category = ['bikes','cars'];
    // const tags = req.body.tags;
    const tags = ['wheels','vehicles','travel','s','s','s'];
    //const imageUrl = req.body.imageUrl;
    const imageUrl = ['https://picsum.photos/200/300','https://picsum.photos/200/300','https://picsum.photos/200/300'];
    try {
    if(tags.length>5){
        const error = new Error('Select only 5 Tags');
        error.statusCode = 406;
        throw error;
    }
    if (!category || category === []){
        const error = new Error('Selected category is empty, select category again');
        error.statusCode = 406;
        throw error;
    }
        const categoryFound = await Category.find({name: {$in:category}}).select('name');
        if (categoryFound) {
            const addProduct = new Product(
                {   name : 'vehicle',
                    description:'Its a good vehicle',
                    categoryId: categoryFound,
                    productImageUrl: imageUrl,
                    creatorId:userId,
                    productRequirement:'buy',
                    tags:tags
                });
          const productSaved = await addProduct.save();
        res.status(200).json({message:productSaved});
        }else{
            const error = new Error('Category not found!');
            error.statusCode = 404;
            throw error;
        }
    } catch (err) {
        if (!err.statusCode) {
            err.statusCode = 500;
        }
        next(err);
    }
};

Errors inside the catch is caught by the express middleware in my app.js.

//Error handling middleware
app.use((error, req, res, next) => {
    const status = error.statusCode || 500;
    const message = error.message;
    res.status(status).json({ message: message, status: status });
});

This works fine. In this specific case, when the array 'tags' are longer than 5, my request from Postman (REST API Dev tool) returns:

{
    "message": "Select only 5 Tags",
    "status": 406
}

When I try to use 'if' checks outside try-catch,I get this error:

 UnhandledPromiseRejectionWarning: Error: Select only 5 Tags
    at exports.postProduct (F:\project\controllers\products.js:17:23)
    at Layer.handle [as handle_request] (F:\project\node_modules\express\lib\router\layer.js:95:5)
    at next (F:\project\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (F:\project\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (F:\project\node_modules\express\lib\router\layer.js:95:5)
    at F:\project\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (F:\project\node_modules\express\lib\router\index.js:335:12)
    at next (F:\project\node_modules\express\lib\router\index.js:275:10)
    at Function.handle (F:\project\node_modules\express\lib\router\index.js:174:3)
    at router (F:\project\node_modules\express\lib\router\index.js:47:12)
    at Layer.handle [as handle_request] (F:\project\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (F:\project\node_modules\express\lib\router\index.js:317:13)
    at F:\project\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (F:\project\node_modules\express\lib\router\index.js:335:12)
    at next (F:\project\node_modules\express\lib\router\index.js:275:10)
    at F:\project\app.js:54:5

Is this way of throwing error inside try-catch for checking length, checking empty array using if statement efficient? Is there any better way to do it?

You are throwing an error but there is no one to catch it. When you create an async function, it returns a promise. So, when you are throwing an error but not catching it, the function is returning a rejected promise. That is why you are getting UnhandledPromiseRejectionWarning . When you are using async/await you must catch the promise rejection using try-catch.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM