Articles

manejo de errores, » try..catch»

Posted by admin

no importa lo buenos que seamos en la programación, a veces nuestros scripts tienen errores. Pueden ocurrir debido a nuestros errores, una entrada inesperada del usuario, una respuesta errónea del servidor y por mil otras razones.

generalmente, un script «muere» (se detiene inmediatamente) en caso de un error, imprimiéndolo en la consola.

pero hay una construcción de sintaxis try..catch que nos permite «atrapar» errores para que el script pueda, en lugar de morir, hacer algo más razonable.,

El «try…catch» sintaxis

El try..catch construcción de dos bloques principales: try y luego catch:

try { // code...} catch (err) { // error handling}

esto funciona así:

  1. en Primer lugar, el código en el try {...} se ejecuta.
  2. Si no hubo errores, entonces catch(err) es ignorado: la ejecución alcanza el final de try y se va, saltar catch.,
  3. si se produce un error, la ejecución try se detiene y el control fluye al principio de catch(err). La variable err (podemos usar cualquier nombre para ella) contendrá un objeto de error con detalles sobre lo que sucedió.

Así, un error dentro de la etiqueta try {…} bloque de no matar a la secuencia de comandos – tenemos una oportunidad de manejarlo en el catch.,

veamos algunos ejemplos.

try..catch solo funciona para los errores de tiempo de ejecución

Para try..catch para el trabajo, el código debe ser ejecutable. En otras palabras, debería ser JavaScript válido.

no funciona si el código es sintácticamente incorrecta, por ejemplo, se ha inigualable llaves:

try { {{{{{{{{{{{{} catch(e) { alert("The engine can't understand this code, it's invalid");}

El motor de JavaScript primero lee el código, y luego lo ejecuta., Los errores que ocurren en la fase de lectura se llaman errores de «tiempo de análisis» y son irrecuperables (desde el interior de ese código). Eso es porque el motor no puede entender el código.

entonces,try..catch solo puede manejar errores que ocurren en código válido. Estos errores se denominan » errores de tiempo de ejecución «o, a veces,»excepciones».

objeto de Error

Cuando se produce un error, JavaScript genera un objeto que contiene los detalles sobre él., El objeto que se pasa como argumento a catch:

try { // ...} catch(err) { // <-- the "error object", could use another word instead of err // ...}

Para todos los integrados en los errores, el objeto de error tiene dos propiedades principales:

nameError de nombre. Por ejemplo, para una variable indefinida que es"ReferenceError".message

mensaje Textual sobre los detalles del error.

Hay otras propiedades no estándar disponibles en la mayoría de los entornos., Una de las más utilizadas y soportadas es:

stackpila de llamadas actuales: una cadena con información sobre la secuencia de llamadas anidadas que llevaron al error. Se utiliza para fines de depuración.

Por ejemplo:

enlace opcional «catch»

una adición reciente
esta es una adición reciente al lenguaje. Los navegadores antiguos pueden necesitar polyfills.,

Si no tenemos detalles del error, catch puede omitirlo:

try { // ...} catch { // <-- without (err) // ...}

el Uso de «try…catch»

Vamos a explorar una de la vida real de casos de uso de try..catch.

como ya sabemos, JavaScript soporta el JSON.método parse (str) para leer valores codificados por JSON.

Por lo general se utiliza para decodificar los datos recibidos a través de la red, desde el servidor u otra fuente.,

lo recibimos y llamamos a JSON.parse así:

Puede encontrar información más detallada sobre JSON en el capítulo métodos JSON, toJSON.

Sijson está mal formado, JSON.parse genera un error, por lo que el script»muere».

¿deberíamos estar satisfechos con eso? ¡Claro que no!

de esta manera, si algo está mal con los datos, el visitante nunca lo sabrá (a menos que abra la consola del desarrollador). Y a la gente realmente no le gusta cuando algo «simplemente muere» sin ningún mensaje de error.,

usemos try..catch para manejar el error:

Aquí usamos el bloque catch solo para mostrar el mensaje, pero podemos hacer mucho más: enviar una nueva solicitud de red, Sugerir una alternativa al visitante, enviar información sobre el error a una instalación de registro,.. Todo mucho mejor que morir.

lanzar nuestros propios errores

¿Qué pasa si json es sintácticamente correcto, pero no tiene una propiedad name?,

let json = '{ "age": 30 }'; // incomplete datatry { let user = JSON.parse(json); // <-- no errors alert( user.name ); // no name!} catch (e) { alert( "doesn't execute" );}

Aquí JSON.parse se ejecuta con normalidad, pero la ausencia de name es en realidad un error para nosotros.

para unificar el manejo de errores, usaremos el operador throw.

operador»Throw»

el operador throw genera un error.

La sintaxis es:

throw <error object>

Técnicamente, se puede usar cualquier cosa como un objeto de error., Esto puede ser incluso primitivo, como un número o una cadena, pero es mejor usar objetos, preferiblemente con propiedades name y message (para permanecer algo compatible con errores incorporados).

JavaScript tiene muchos construidos en los constructores de los errores estándar: Error, SyntaxError, ReferenceError, TypeError y otros. También podemos usarlos para crear objetos de error.,

Su sintaxis es:

let error = new Error(message);// orlet error = new SyntaxError(message);let error = new ReferenceError(message);// ...

Para los errores integrados (no para todos los objetos, de los errores), el name la propiedad es exactamente el nombre del constructor. Y message se toma del argumento.,

Por ejemplo:

let error = new Error("Things happen o_O");alert(error.name); // Erroralert(error.message); // Things happen o_O

Vamos a ver qué tipo de error JSON.parse genera:

try { JSON.parse("{ bad json o_O }");} catch(e) { alert(e.name); // SyntaxError alert(e.message); // Unexpected token b in JSON at position 2}

Como podemos ver, que el SyntaxError.

Y en nuestro caso, la ausencia de name es el error, ya que los usuarios deben tener un name.,

así que vamos a lanzarlo:

en la línea(*), el operadorthrowgenera unSyntaxErrorcon elmessage, de la misma manera que JavaScript lo generaría él mismo . La ejecución de try se detiene inmediatamente y el flujo de control salta a catch.

Ahora catch se convirtió en un solo lugar para todo el manejo de errores: tanto para JSON.parse y otros casos.,

Regeneración de

En el ejemplo anterior, podemos usar try..catch para manejar datos incorrectos. Pero, ¿es posible que se produzca otro error inesperado dentro del bloque try {...}? Como un error de programación (la variable no está definida) o algo más, no solo esta cosa de «datos incorrectos».

Por ejemplo:

por supuesto, todo es posible! Los programadores cometen errores. Incluso en las utilidades de código abierto utilizadas por millones durante décadas, de repente se puede descubrir un error que conduce a terribles hacks.,

en nuestro caso, try..catch se coloca para detectar errores de «datos incorrectos». Pero por su naturaleza, catchobtiene todos los errores de try. Aquí se obtiene un error inesperado, pero todavía muestra el mismo mensaje "JSON Error". Eso está mal y también hace que el código sea más difícil de depurar.

para evitar tales problemas, podemos emplear la técnica de «repensar». La regla es simple:

Catch solo debe procesar los errores que conoce y «repensar» todos los demás.,

la técnica de «repensar» se puede explicar con más detalle como:

  1. Catch obtiene todos los errores.
  2. En el bloque catch(err) {...} analizamos el objeto de error err.
  3. si no sabemos cómo manejarlo, lo hacemos throw err.

Generalmente, podemos verificar el tipo de error usando el operador instanceof:

También podemos obtener el nombre de la clase de error de la propiedad err.name. Todos los errores nativos lo tienen. Otra opción es leer err.constructor.name.,

En el código a continuación, utilizamos la regeneración de modo que catch maneja SyntaxError:

El error de lanzar en línea (*) dentro de catch bloque «cae» de try..catch y puede ser capturado por una capa exterior de try..catch construir (si es que existe), o mata a la secuencia de comandos.

así que el bloquecatch en realidad solo maneja los errores que sabe cómo tratar y «omite» todos los demás.,

El siguiente ejemplo muestra cómo dichos errores pueden ser capturados por un mayor nivel de try..catch:

Aquí readData sólo sabe cómo manejar SyntaxError, mientras que el exterior try..catch sabe cómo manejar todo.

try…catch…finally

Espere, eso no es todo.

la construcción try..catch puede tener una cláusula de código más: finally.,

Si es que existe, se ejecuta en todos los casos:

  • después de try, si no hubo errores,
  • después de catch, si hubo errores.

La sintaxis extendida se parece a esto:

try { ... try to execute the code ...} catch(e) { ... handle errors ...} finally { ... execute always ...}

Trate de ejecutar este código:

try { alert( 'try' ); if (confirm('Make an error?')) BAD_CODE();} catch (e) { alert( 'catch' );} finally { alert( 'finally' );}

El código tiene dos modos de ejecución:

  1. Si usted contesta «Sí» a «Hacer un error?»entonces try -> catch -> finally.,
  2. Si dices «No», entonces try -> finally.

la cláusula finally se usa a menudo cuando comenzamos a hacer algo y queremos finalizarlo en cualquier caso de resultado.

por ejemplo, queremos medir el tiempo que tarda una función Fibonacci numbers fib(n). Naturalmente, podemos empezar a medir antes de que se ejecute y terminar después. Pero, ¿qué pasa si hay un error durante la llamada a la función? En particular, la implementación de fib(n) en el siguiente código devuelve un error para números negativos o no enteros.,

la cláusula finally es un gran lugar para terminar las mediciones sin importar qué.

Aquí finally garantiza que el tiempo se mide correctamente en ambas situaciones – en el caso de una ejecución exitosa de fib y en caso de un error en ella:

Usted puede comprobar ejecutando el código con la introducción de 35 dentro de prompt se ejecuta normalmente, finally después de try., Y luego ingrese -1 div – – habrá un error inmediato, y la ejecución tomará 0ms. Ambas mediciones se realizan correctamente.

En otras palabras, la función puede terminar con return o throw, que no importa. La cláusula finally se ejecuta en ambos casos.,

Variables locales dentro de try..catch..finally

por Favor, tenga en cuenta que result y diff variables en el código anterior se declaran antes de try..catch.

de lo contrario, si declaramos let en el bloque try, solo sería visible dentro de él.

try..finally

El try..finally construir, sin catch cláusula, también es útil., Lo aplicamos cuando no queremos manejar errores aquí (dejarlos caer), pero queremos asegurarnos de que los procesos que iniciamos estén finalizados.

function func() { // start doing something that needs completion (like measurements) try { // ... } finally { // complete that thing even if all dies }}

En el código anterior, un error dentro de try siempre se cae, porque no hay ninguna catch. Pero finally funciona antes de que el flujo de ejecución salga de la función.

global catch

específico del entorno

la información de esta sección no forma parte del núcleo de JavaScript.,

imaginemos que tenemos un error fatal fuera de try..catch, y el script murió. Como un error de programación o alguna otra cosa terrible.

¿Hay alguna manera de reaccionar ante tales ocurrencias? Es posible que queramos registrar el error, mostrar algo al usuario (normalmente no ven mensajes de error), etc.

no hay ninguno en la especificación, pero los entornos generalmente lo proporcionan, porque es realmente útil. Por ejemplo, Node.js tiene process.on("uncaughtException") para eso. Y en el navegador podemos asignar una función a la ventana especial.,propiedad onerror, que se ejecutará en caso de un error no capturado.

La sintaxis:

window.onerror = function(message, url, line, col, error) { // ...};

message mensaje de Error. url URL del script donde ocurrió el error. line, col números de Línea y columna donde el error ocurrió. error objeto de Error.,

por ejemplo:

el rol del controlador global window.onerror generalmente no es recuperar la ejecución del script, probablemente sea imposible en caso de errores de programación, sino enviar el mensaje de error a los desarrolladores.

funcionan así:

  1. Nos registramos en el servicio y obtenemos un trozo de JS (o una URL de script) de ellos para insertar en las páginas.
  2. ese script JS establece una función personalizada window.onerror.
  3. cuando se produce un error, envía una solicitud de red al servicio.
  4. podemos iniciar sesión en la interfaz web del servicio y ver los errores.,

Summary

la construcción try..catch permite manejar errores de tiempo de ejecución. Literalmente permite» intentar «ejecutar el código y» atrapar » los errores que pueden ocurrir en él.

la sintaxis es:

puede no haber catchsection o no finally, por lo que las construcciones más cortas try..catchy try..finally también son válidas.

los objetos de Error tienen las siguientes propiedades:

  • message – el mensaje de error legible por humanos.,
  • name div – – la cadena con el nombre de error (nombre del constructor de error).
  • stack(no estándar, pero bien soportado) – la pila en el momento de la creación del error.

si no se necesita un objeto de error, podemos omitirlo usando catch {en lugar de catch(err) {.

También podemos generar nuestros propios errores utilizando el operador throw., Técnicamente, el argumento de throw puede ser cualquier cosa, pero generalmente es un objeto de error heredado de la clase incorporada Error. Más sobre la extensión de errores en el próximo capítulo.

repensar es un patrón muy importante de manejo de errores: un bloquecatch generalmente espera y sabe cómo manejar el tipo de error en particular, por lo que debe repensar errores que no sabe.

incluso si no tenemos try..catch, la mayoría de los entornos nos permiten configurar un controlador de errores «global» para detectar errores que «caen»., En el navegador, eso es window.onerror.

Leave A Comment