Análisis de cómo Node maneja los errores

Node es un lenguaje con altos requisitos para el manejo de errores. Si el manejo de errores no está en su lugar, puede hacer que el proceso del programa salga

Inserte la descripción de la imagen aquí

01 Prefacio


El manejo de errores es una parte importante del programa, y ​​también es un estándar para juzgar si su programa es profesional. En términos generales, cuando escribimos un programa, elegiremos usar try ... catch para detectar el error, oa veces usaremos throw para arrojar el error. Este es un método de captura de errores comúnmente utilizado. Pero cuando estamos desarrollando un nodo, estaremos expuestos a la gestión de errores durante el proceso asincrónico.

Sabemos que se utilizarán muchos módulos de terceros durante el desarrollo del nodo. Por ejemplo, a menudo usamos la herramienta de administración de paquetes más grande npm. Los paquetes descargados se colocarán en node_modules en nuestro proyecto. Hay muchos archivos y la cantidad de código es enorme. Habrá muchos errores ocultos en él, y es muy útil utilizar la captura de errores en este momento.

De hecho, lo que pensábamos al principio era monitorear los errores a escala global. El nodo proporciona una excepción no capturada para detectar excepciones, pero de esta manera nos resultará difícil localizar la ubicación del error. Esta función no debe considerarse como un módulo de captura universal, sino la solución final.
Inserte la descripción de la imagen aquí

02 Módulo de error


Error define los tipos de error comunes en el Nodo. ​​Podemos usar Error para arrojar errores. El módulo Error contiene una traza de pila utilizada para describir dónde se genera el error. En términos generales, podemos saber exactamente en qué parte del código se produjo el error. De acuerdo con la información de descripción del error, el error puede ubicarse rápidamente.

var fs = require("fs");
fs.readFile("file",function(err,data){
	if(err){
		throw new Error("Error!")
	}
})

Todos los errores generados en el programa Node son instancias de la clase Error o se heredan de la clase Error. No solo podemos usar el módulo de error que viene con la función de devolución de llamada en el código del programa, sino que también podemos mostrar el primer error capturado. Por ejemplo, cuando sabe que cierta parte del código lógico está mal, debe capturar y recordar el error, puede usar:

throw new Error("自定义错误信息!")

03 Método de captura de errores


A continuación, vamos a presentar brevemente cómo capturamos errores en Node. En general, podemos tener los siguientes tres métodos, try / catch, callback y event. El método try / catch que usamos antes solo es adecuado para situaciones de llamada síncrona, pero sabemos que habrá muchos métodos de llamada asíncrona en el nodo.

trata de atraparlo

En primer lugar, debemos entender que este método no puede detectar errores durante las operaciones asincrónicas. La razón principal es que el contexto del código ha cambiado cuando regresa la llamada asincrónica, y el código en la función de devolución de llamada ha dejado el alcance de try / catch, por lo que es imposible. Capturado

Situación de llamada síncrona:

//这里可以捕获
try{
	throw new Error("这里出错了!");
}catch(e){
	console.log(e)
}

Situación de llamada asincrónica:

try{
	setTimeout(function(){throw new Error('这里出错了!')}1000)
}catch(e){
	console.log(e);//这里无法进行捕获
}
llamar de vuelta

El método de la función de devolución de llamada está determinado principalmente por el juicio de los parámetros.Por lo general, la función de devolución de llamada en el nodo aceptará dos parámetros de error y resultado. Uno de estos dos valores definitivamente no será nulo. Tomemos un ejemplo leyendo el archivo local. (Debido a que el método devuelve el objeto buffer es difícil de leer, solo usamos utf8 para leer, y finalmente la cadena se convierte en json)

var fs = require("fs");
fs.readFile("./a.json",'utf8', function(error, result) {
  if (error) {
    console.log(error);
    return;
  }
  console.log(JSON.parse(result));
});

Si el archivo existe, se devolverá el resultado de salida. Si a1.json se escribe intencionalmente, arrojará un error:

{ [Error: ENOENT: no such file or directory, open 'D:\test\a1.json']
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'D:\\test\\a1.json' }
Manejo de errores de eventos

Cuando monitoreamos la secuencia del archivo, incluso si la lectura de la secuencia del archivo es un método sincrónico, todavía no podemos usar try / catch para capturar, ¿por qué? Debido a que este método devuelve un objeto, solo puede usar el método de manejo de eventos para manejar la excepción. Si usa try / catch, informará directamente un error y saldrá. El uso del método de monitoreo de eventos no afectará la operación del programa e informará un mensaje de error.

Entonces, la forma correcta debería ser así:

var fs = require("fs");
var stream = fs.createReadStream('./a.json');
stream.on("error",function(err){
	console.log(err)
})

04 Módulo de dominio


La vista del módulo de dominio resuelve los tres errores mencionados anteriormente (que pueden manejar la devolución de llamada y los formularios de eventos) en una dimensión superior, pero este módulo ahora está en desuso. En primer lugar, su punto de partida es unificar diferentes métodos de procesamiento en este módulo para monitorear y capturar.

Su uso es usar el método de creación para crear el objeto Dominio, luego escuchar el evento de error de un objeto a través del objeto Dominio y definir la lógica de procesamiento correspondiente, y finalmente usar el método de ejecución para iniciar todo el Dominio, el contenido del método de ejecución es lo que preparamos El código de monitoreo.

//处理callback
var fs = require("fs");
var domain = require("domain");

var d = domain.create();
d.run(function(){
    fs.readFile('./a1.json','utf8',function(err,data){
        if(err){
            throw new Error('error')
        }
        console.log(data)
    })
})

d.on('error',function(err){
    console.log(err)
})
//处理event
var fs = require("fs");
var domain = require("domain");

var d = domain.create();
d.run(function(){
    fs.createReadStream('./a1.json')
})

d.on('error',function(err){
    console.log(err)
})

Además, el dominio puede admitir la llamada manual al método add para agregar objetos a la lista de escucha. Se puede ver a partir de esto que el Dominio en realidad envuelve los objetos a administrar y luego los procesa e implementa a través de los métodos de ejecución y adición. Pero si queremos monitorear todo el servicio web, ponemos todo el código en el método de ejecución, lo que puede causar pérdidas de memoria, y es difícil aceptar llamar manualmente al método add. Si el objeto se pierde, puede tomar mucho tiempo cometer errores Solucionar problemas

Su principio es realmente muy simple:

  • Agregue el objeto a su lista de monitoreo a través del método add (hay un atributo menber para mantener el objeto monitoreado)
  • Escuche la captura de process.uncaughtException, si el código está envuelto en el dominio desencadenará el evento de error de dominio
  • Al agregar una implementación asincrónica al dominio para monitorear, de modo que todos los diferentes mecanismos de manejo de errores se puedan unificar en un solo objeto

05 Manejo de errores en ES6


Utilizamos ES6 más en nuestro trabajo, por ejemplo, a menudo usamos objetos de promesa y la forma de asíncrono / espera, que se llama la solución definitiva de asíncrono. Entonces, hablemos sobre cómo manejar los errores en ES6.

Promesa

En primer lugar, el primero debe ser una promesa, ya que es muy amigable con el funcionamiento de la función de devolución de llamada, evita la generación de algún infierno de devolución de llamada, y también proporciona una forma de excepciones try / catch para capturar.

var promise = new Promise((resolve,reject){
	throw new Error("出错啦!")
})
promise.catch(function(error){
	console.log(error);
})

Generador 与 asíncrono

Puede usar la declaración try / catch para la captura de errores. Cuando se produce un error en la operación asincrónica después del rendimiento, también puede usar la declaración try para la captura.

function * generator(){
	try{
		yield asyncFunction();
	}catch(e){
		console,log(e)
	}
	return 'end'
}

Si escribimos en forma de asíncrono (de hecho, es azúcar sintáctico, la esencia es la misma), también podemos usar try / catch para capturar. Si la operación interna de await es incorrecta, el código posterior no se ejecutará y puede usar try para envolverlo.

async function test(){
	try{
		await asyncFunction()
	}catch(e){
		console.log(e)
	}
}

06 Resumen

Anteriormente presentamos cómo detectar errores en el mundo asincrónico. El código que escribimos antes estaba en el mundo síncrono. Usar try / catch puede resolver la mayoría de sus problemas. Pero en los últimos años hemos visto Node, y el mundo de la sincronización se ha roto, por lo que también debemos aprender a detectar errores.

Anteriormente hablamos sobre el uso del método original try / catch, función de devolución de llamada de devolución de llamada, mecanismo de activación de eventos tres métodos.

Si encontramos algunos errores inevitables que hacen que el sistema se bloquee o que el programa no se ejecute correctamente, todavía tenemos una solución final y la mayoría de ellos son efectivos, es decir: ¡intente reiniciar!

Inserte la descripción de la imagen aquí

Publicado 57 artículos originales · ganado elogios 6 · vistas 6419

Supongo que te gusta

Origin blog.csdn.net/weixin_42724176/article/details/105285195
Recomendado
Clasificación