proyecto - ¿Principios de manejo de errores para las aplicaciones Node.js+Express.js?
node js express tutorial (3)
¿Por qué primer parámetro?
Debido a la naturaleza asíncrona de Node.js, el patrón de primer parámetro como errar se ha establecido como una convención para el manejo de errores de Node.js de usuario . Esto es porque asincrónico:
try {
setTimeout(function() {
throw ''something broke'' //Some random error
}, 5)
}
catch(e) {
//Will never get caught
}
Así que, en cambio, tener el primer argumento de la devolución de llamada es prácticamente la única forma sensata de pasar errores de forma asíncrona, además de simplemente lanzarlos.
Hacerlo dará lugar a una unhandled exception
que, en la forma en que suena, implica que no se hizo nada para sacar la aplicación de su estado confuso.
Excepciones, ¿por qué existen?
Sin embargo, vale la pena señalar que prácticamente todas las partes de Node.js son emisores de eventos y el lanzamiento de una excepción es un evento de bajo nivel que se puede gestionar como todos los eventos:
//This won''t immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
console.error("calm down...", err)
});
Esto no se puede llevar al extremo para detectar todos los errores y hacer una aplicación que hará todo lo posible para nunca fallar. Esta es una idea terrible en casi todos los casos de uso, ya que dejará al desarrollador sin idea de lo que está sucediendo en el estado de la aplicación y es análogo a envolver main en try-catch.
Dominios: agrupación de eventos lógicamente
Como parte del tratamiento de este problema de excepciones que hacen que las aplicaciones se caigan, los domains permiten al desarrollador tomar, por ejemplo, la aplicación Express.js, y tratar de cerrar las conexiones de manera sensata en caso de una falla catastrófica.
ES6
Probablemente esté mencionando que esto cambiará nuevamente ya que ES6 permite que el patrón del generador cree eventos asíncronos que aún son detectables con los bloques try / catch.
Koa (escrito por TJ Holowaychuck, el mismo autor original de Express.js) hace esto notablemente. Utiliza la declaración de yield
ES6 para crear bloques que, aunque aparecen casi sincrónicos, se manejan de la forma asíncrona de nodo habitual:
app.use(function *(next) {
try {
yield next;
}
catch (err) {
this.status = err.status || 500;
this.body = err.message;
this.app.emit(''error'', err, this);
}
});
app.use(function *(next) {
throw new Error(''some error'');
})
Este ejemplo fue descaradamente robado de here .
Parece que el informe / manejo de errores se realiza de forma diferente en las aplicaciones Node.js + Express.js comparación con otros marcos. ¿Estoy en lo cierto al entender que funciona de la siguiente manera?
A) Detecta errores al recibirlos como parámetros de tus funciones de devolución de llamada. Por ejemplo:
doSomethingAndRunCallback(function(err) {
if(err) { … }
});
B) Informe errores en MIDDLEWARE llamando al siguiente (err). Ejemplo:
handleRequest(req, res, next) {
// An error occurs…
next(err);
}
C) Informe errores en RUTAS arrojando el error. Ejemplo:
app.get(''/home'', function(req, res) {
// An error occurs
throw err;
});
D) Maneje los errores configurando su propio manejador de errores a través de app.error () o use el manejador genérico de errores Connect. Ejemplo:
app.error(function(err, req, res, next) {
console.error(err);
res.send(''Fail Whale, yo.'');
});
¿Estos cuatro principios son la base de todo el manejo / reporte de errores en las aplicaciones Node.js + Express.js?
El manejo de errores en Node.js generalmente tiene el formato A). La mayoría de las devoluciones devuelven un objeto de error como primer argumento o null
.
Express.js utiliza middleware y la sintaxis de middleware utiliza B) y E) (se menciona a continuación).
C) es una mala práctica si me preguntas.
app.get(''/home'', function(req, res) {
// An error occurs
throw err;
});
Puede reescribir fácilmente lo anterior como
app.get(''/home'', function(req, res, next) {
// An error occurs
next(err);
});
La sintaxis del middleware es válida en una solicitud de get
.
En cuanto a D)
(07:26:37 PM) tjholowaychuk: app.error se elimina en 3.x
TJ acaba de confirmar que app.error
está en desuso en favor de E
MI)
app.use(function(err, req, res, next) {
// Only handle `next(err)` calls
});
Cualquier middleware que tenga una longitud de 4 (4 argumentos) se considera middleware de error. Cuando uno llama a next(err)
connect goes y llama al middleware basado en errores.
La gente de Joyent ha publicado un documento muy revelador sobre las mejores prácticas al respecto. Un artículo imprescindible para cualquier desarrollador de Node.js.