0

There's single api application like this:

const express = require('express')
const app = express()
const router = require('express').Router()
...
route.post('/dogs', (req, res, next) => {
  const dog = new Dog() // it defined in real app
  dog.validate() // error happens here
    .then(() => {
      return res.status(201)
    })
    // [1]
})
...
app.use('/api/v1', router)
app.use(notFoundErrorHandler)
app.use(globalErrorHandler)

function notFoundErrorHandler (req, res, next) {
  res.status(404)
  res.send({error: 'Not found'})
}

function globalErrorHandler (err, req, res, next) {
  if (err) {
    res.status(err.status || 500)
    res.json({error: err.message || err})
  }
}

If there's validation error it won't pass to the globalErrorHandler, but catching and rethrowing error solves the problem [1]:

.catch(err => { return next(err) })

Does this behaviour is normal for mongoose with not complete Promise implimentation, or it could be implimentated in another way?

It doesn't raise error when using other methods like save, find, etc.

Iworb
  • 522
  • 7
  • 29
  • I thought that v5 [solve this problem](https://github.com/Automattic/mongoose/issues/3483), but no, I still got the same error output to console instead of response – Iworb Jan 18 '18 at 08:42
  • Does your request hang? – Stamos Jan 18 '18 at 08:55
  • Yes, request hanged up and I've got "UnhandledPromiseRejectionWarning: Unhandled promise rejection" into console. – Iworb Jan 18 '18 at 09:07

1 Answers1

0

Thats normal, yes and has nothing to do with mongoose but with Express. Express doesn't handle unhanded exceptions implicit, you will have to handle them explicit. So in each route you will have to catch any errors and pass them to next.

I know that this may be frustrating sometimes so I would suggest that you create a route manager of sorts that will register each route with an action handler and a try/catch pattern.

There are many examples out there, here is one simple I like.

 var dogHandler = require('dogHandler')

 var serverRoutes = [{
     path: "dogs",
     method: "post",
     action: dogHandler
 }]

 serverRoutes.forEach(route => {
     app[route.method](route.path, (request, response, next) => {
         route.action(request, response)
             .then(() => next)
             .catch(err => next(err));
     });
 });
Stamos
  • 3,938
  • 1
  • 22
  • 48