2011-10-10 14 views
23

Estoy empezando a trabajar con Express JS y me he encontrado con un problema. Parece que no puedo descubrir la forma correcta de manejar los errores.¿Cómo manejar adecuadamente los errores en Express?

Por ejemplo, tengo una API de servicios web que sirve un objeto llamado "evento". Me gustaría devolver una cadena simple de "no puedo encontrar el evento" cuando un usuario envía una identificación de evento que no se encuentra. Aquí es cómo estoy actualmente estructurar mi código:

app.get('/event/:id', function(req, res, next) { 
    if (req.params.id != 1) { 
     next(new Error('cannot find event ' + req.params.id)); 
    } 

    req.send('event found!'); 
}); 

Cuando envío un id distinto de 1, Nodo bloquea con el siguiente resultado:

http.js:527 
    throw new Error("Can't set headers after they are sent."); 
     ^
Error: Can't set headers after they are sent. 
    at ServerResponse.<anonymous> (http.js:527:11) 
    at ServerResponse.setHeader (/usr/local/kayak/node_modules/express/node_modules/connect/lib/patch.js:62:20) 
    at /usr/local/kayak/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js:72:19 
    at [object Object].<anonymous> (fs.js:107:5) 
    at [object Object].emit (events.js:61:17) 
    at afterRead (fs.js:878:12) 
    at wrapper (fs.js:245:17) 

De lo que puedo decir por el uso de el node.js depurador, la ejecución del bloque de código continúa después de llamar al next(), lo que significa que req.send('event found!') intenta ejecutarse. No quiero que esto suceda.

La única solución que he encontrado es simplemente arrojar un new Error() en lugar de "al lado", pero esto da como resultado que se genere una página de error Express HTML predeterminada. Me gustaría un poco más de control que eso.

Me he tomado el tiempo para leer el error handling section de la documentación de Express, pero no pude darle sentido.

Respuesta

35

Le recomendamos echar un vistazo a Express Error Handling. A partir de ahí:

app.param('userId', function(req, res, next, id) { 
    User.get(id, function(err, user) { 
     if (err) return next(err); 
     if (!user) return next(new Error('failed to find user')); 
     req.user = user; 
     next(); 
    }); 
}); 

El punto dulce que se echa en falta es el returnnext(...)

10

usted tiene un par de problemas en su código:

  • al responder a la cliente, necesita utilizar el respuesta objeto (res en lugar de req).

  • Cuando se envía un error al next, debe retorno, por lo que el resto de la función no se ejecuta.

Aquí está tu código después de la fijación de los errores:

app.get('/event/:id', function(req, res, next) { 
    if (req.params.id != 1) { 
     return next(new Error('cannot find event ' + req.params.id)); 
    } 

    res.send('event found!'); // use res.send (NOT req.send) 
}); 
18

Eso es porque estás haciendo mal: que ya pasó un error (que será procesada por Express y devolver un 500 - Página de error para el usuario o algo así) pero también está tratando de enviar su propia respuesta al cliente: res.send ('evento encontrado!');

que realmente debe echa un vistazo a la guía expreso sobre Manejo de errores aquí: http://expressjs.com/guide/error-handling.html

Lo que yo haría en su ejemplo es:

function NotFound(msg){ 
    this.name = 'NotFound'; 
    Error.call(this, msg); 
    Error.captureStackTrace(this, arguments.callee); 
} 

app.get('/event/:id', function(req, res, next){ 
    if (req.params.id != 1) { 
    throw new NotFound('Cannot find event ' + req.params.id); 
    } else { 
    res.send('event found!'); 
    } 
}); 

app.error(function(err, req, res, next){ 
    if (err instanceof NotFound) { 
     res.render('404.ejs'); 
    } else { 
     next(err); 
    } 
}); 
+5

que expresan la documentación en el enlace es bastante pobre sin embargo.Ni siquiera menciona cómo se supone que debes lanzar correctamente un error, o para qué versión de express es válido. – UpTheCreek

+0

Ese es el enlace de Express 3.x, si desea saber más sobre el manejo de errores en 2.x, visite este enlace: http://expressjs.com/2x/guide.html#error-handling – alessioalex

+0

Gracias, eso es útil. – UpTheCreek

Cuestiones relacionadas