简体   繁体   中英

Axios + Sequelize ValidationError = no request or response objects in promise catch block? How to handle?

Typically, I have Axios calls that look something like this:

api.post('/users/add', (req, res, next) => {
  Users.create(req.body).then(userResult => {
    // misc code here
    return res.json(userResult)
  }).catch((err, req, res, next) => {
    if (err) {
      // handle the error by sending to the application error handler
      next(err);
    }
  });
});

The problem I'm having is that req, res, and next do not seem to exist if the error is a Sequelize validation error. So I add a check inside the IF like this:

if (err) {
  if (err instanceof Sequelize.ValidationError) {
    // i've tried a lot here and am stuck as to what to do
  } else {
    // handle other errors
  }
}

I can inspect the error just fine once I'm in that inner IF, but I don't know what to do to get a response back out to the calling browser. I also can't call next() and bubble up the error to my regular error handler since it doesn't recognize next(). And if I could, the items I usually use from req or res aren't available.

I've gone over all of the documentation on the Sequelize website, pored over the issue queue, searched here on stackoverflow, and can't seem to find the same problem. I assume, therefore, the solution is something simple that is just a gap in my knowledge. Please enlighten me. How do I either get this to bubble up to my general error handler or return a response to the browser from here?

You should not redefine req , res , and next in the catch. They will be accessible from the parent scope but by including them in the catch they will be undefined as a then/catch will only have a single argument.

/* create a POST route. for /users/add requests it will 
   call a function passing in req, res, next() */
api.post('/users/add', (req, res, next) => { // this syntax creates an "arrow function"
  /* note that it's probably a bad idea to just 
     pass in the request.body without sanitizing */
  return Users.create(req.body)    // call Sequelize and get a Promise
    .then((userResult) => {        // success, userResult will be the new user
      return res.json(userResult); // use res.json() to send to client
    })
    .catch((err) => {              // create failed
      return next(err);            // pass the err along to next()
    });
});

If you want to write the same code with async/await which lets you write asynchronous code in a synchronous syntax. When you add async the function will automatically return a Promise. Using await will wait for a Promise to resolve (or throw an error) without going into indendentation hell (in this case the result of the user creation).

api.post('/users/add', async (req, res, next) => {
  try {
    const user = await Users.create(req.body);
    return res.json(userResult);
  } catch (err) {
    return next(err);
  }
});

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