Home > Software design >  Chaining promisses. How I can use catch to return error?
Chaining promisses. How I can use catch to return error?

Time:08-01

I am new to Node and I am trying to create an order with a product only in that product exists. I am using mongoose express.

In my mind it should work like: Request to create order (with product and quantity) -> check DB if product exists -> create order -> insert into DB -> response.

I would like my code to work like

Product.find(productId).then(if exists create order insertdb).then(receives inserted -> create response).catch(if error respond error).

This is my code right now:

router.post("/", (req, res, next) => {
  Product.findById(req.body.productId)
    .then((product) => {
      if (!product) {
        res.status(404).json({ error: "Product not found" });
        return;
      }
      console.log("Product:"   product);
      const order = new Order({
        _id: new mongoose.Types.ObjectId(),
        product: req.body.productId,
        quantity: req.body.quantity,
      });
      return order.save();
    })
    .then((doc) => {
      console.log(doc);
      if (!doc) {
        return;
      }
      res.status(201).json({
        message: "Order created",
        createdOrder: {
          _id: doc._id,
          product: doc.product,
          quantity: doc.quantity,
          request: {
            type: "GET",
            url: "http://localhost:3000/orders/"   doc._id,
          },
        },
      });
    })
    .catch((err) => {
      console.log(err);
      res.status(500).json({ error: err });
    });
});

However I am checking if doc exists on my second .then() before returning. Is there a recommended way to prevent execution of my chain in the if(!product) block?

I tried:

  1. Using throw new Error(404); instead of return but I got "Cannot set headers after they are sent to the client" because of the res.status(500) in the catch block.
  2. return res.status(404).json({ error: "Product not found" }); but same error as 1.

CodePudding user response:

This could be more readable with async/await. You don't need to make extra DB call to get the saved order, since it is returned by .save

router.post("/", async (req, res, next) => {
                try {
                    let product = await Product.findById(req.body.productId);

                    if (!product) {
                        res.status(404).json({
                            error: "Product not found"
                        });
                    } else {
                        const order = new Order({
                            _id: new mongoose.Types.ObjectId(),
                            product: req.body.productId,
                            quantity: req.body.quantity,
                        });

                        let orderReturned = await order.save();

                        res.status(201).json({
                                message: "Order created",
                                orderReturned
                            }
                        }
                        catch (err) {
                            res.status(500).json({
                                error: err
                            });
                        }
                    })
  • Related