try...catch

La declaraci贸n try...catch se帽ala un bloque de instrucciones a intentar (try), y especifica una respuesta si se produce una excepci贸n (catch).

Sintaxis

try {
   try_statements
}
[catch (exception_var_1 if condition_1) { // non-standard
   catch_statements_1
}]
...
[catch (exception_var_2) {
   catch_statements_2
}]
[finally {
   finally_statements
}]
try_statements
Las sentencias que ser谩n ejecutadas.
catch_statements_1, catch_statements_2
Sentencias que se ejecutan si una excepci贸n es lanzada en el bloque try.
exception_var_1, exception_var_2
Identificador que contiene un objeto de excepcion asociado a la cl谩usula catch.
condition_1
Una expresi贸n condicional.
finally_statements
Sentencias que se ejecutan despu茅s de que se completa la declaraci贸n try . Estas sentencias se ejecutan independientemente de si una excepcion fue lanzada o capturada.

Descripci贸n

La sentencia try consiste en un bloque try que contiene una o m谩s sentencias. Las llaves {} se deben utilizar siempre, incluso para una bloques de una sola sentencia. Al menos un bloque catch o un bloque finally debe estar presente. Esto nos da tres formas posibles para la sentencia try:

  1. try...catch
  2. try...finally
  3. try...catch...finally

Un bloque catch contiene sentencias que especifican que hacer si una excepci贸n es lanzada en el bloque try. Si cualquier sentencia dentro del bloque try (o en una funcion llamada desde dentro del bloque try) lanza una excepci贸n, el control cambia inmediatamente al bloque catch . Si no se lanza ninguna excepcion en el bloque try, el bloque catch se omite.

La bloque finally se ejecuta despues del bloque try y el/los bloque(s) catch hayan finalizado su ejecuci贸n. 脡ste bloque siempre se ejecuta, independientemente de si una excepci贸n fue lanzada o capturada.

Puede anidar una o m谩s sentencias try. Si una sentencia try interna no tiene una bloque catch, se ejecuta el bloque catch de la sentencia try que la encierra.

Usted tambi茅n puede usar la declaraci贸n try para manejar excepciones de JavaScript. Consulte la Gu铆a de JavaScript para obtener mayor informaci贸n sobre excepciones de JavaScript.
 

Bloque catch incondicional

Cuando solo se utiliza un bloque catch, el bloque catch es ejecutado cuando cualquier excepci贸n es lanzada. Por ejemplo, cuando la excepci贸n ocurre en el siguiente c贸digo, el control se transfiere a la cl谩usula catch.

try {
   throw "myException"; // genera una excepci贸n
}
catch (e) {
   // sentencias para manejar cualquier excepci贸n
   logMyErrors(e); // pasa el objeto de la excepci贸n al manejador de errores
}

El bloque catch especif铆ca un identificador ( e en el ejemplo anterior) que contiene el valor de la excepci贸n. Este valor est谩 solo disponible en el scope de el bloque catch

Bloques catch condicionales

Tambien se pueden crear "bloques catch condicionales", combinando bloques try...catch con estructuras  if...else if...else como estas:

try {
    myroutine();  // puede lanzar tres tipos de excepciones
} catch (e) {
    if (e instanceof TypeError) {
        // sentencias para manejar excepciones TypeError
    } else if (e instanceof RangeError) {
        // sentencias para manejar excepciones RangeError
    } else if (e instanceof EvalError) {
        // sentencias para manejar excepciones EvalError
    } else {
       // sentencias para manejar cualquier excepci贸n no especificada
       logMyErrors(e); // pasa el objeto de la excepci贸n al manejador de errores
}

El identificador de excepciones

Cuando una excepci贸n es lanzada en el bloque try, exception_var (por ejemplo, la e en catch (e)) guarda el valor de la excepci贸n. Se puede usar 茅ste identificador para obtener informaci贸n acerca de la excepci贸n que fue lanzada. Este valor est谩 solo disponible en el scope de el bloque catch.

function isValidJSON(text) {
  try {
    JSON.parse(text);
    return true;
  } catch {
    return false;
  }
}

La cl谩usula finally

La cl谩usula finally contiene sentencias a ejecutarse despu茅s de que las cl谩usulas try y catch se ejecuten, pero antes de las sentencias que le siguen al bloque try..catch..finally. Note que la cl谩usula finally se ejecuta sin importar si una excepci贸n es o no lanzada. Si una excepci贸n es lanzada, las instrucciones en la cl谩usula finally se ejecutan incluso si ninguna cl谩usula catch maneja la excepci贸n.

Usted puede usar la cl谩usula finally para hacer que su script falle pl谩cidamente cuando una excepci贸n ocurra; por ejemplo, para hacer una limpieza general, usted puede necesitar liberar un recurso que su script haya retenido.

Puede parecer extra帽o tener una cl谩usula relacionada a una excepci贸n que se ejecuta sin importar si hay una excepci贸n o no, pero esta concepci贸n en realidad sirve a un prop贸sito. El punto importante no es que la cl谩usula finally siempre se ejecuta, si no m谩s bien que el codigo ordinario que le sigue a try..catch no.

Por ejemplo, si otra excepci贸n ocurre dentro de un bloque catch de una declaraci贸n try, cualquier codigo restante en el mismo bloque exterior try que encierra ese try..catch (o en el flujo principal, si no es un bloque try exterior) , no ser谩 ejecutado, dado que el control es inmediatamente transferido al bloque catch del try exterior (o el generador de error interno, si no es en un bloque try).

Por lo tanto, cualquier rutina de limpieza hecha en esa secci贸n encerrada (o la principal) antes de que exista, ser谩 saltada. Sin embargo, si la declaraci贸n try tiene un bloque finally, entonces el c贸digo de ese bloque finally ser谩 ejecutado primero para permitir tal limpieza, y ENTONCES el bloque catch de la otra declaraci贸n try (o el generador de error) tomar谩 el control para manejar la segunda excepci贸n.

Ahora, si esa rutina de limpieza debiera ser hecha ya sea que el c贸digo del try..catch tenga 茅xito o no, entonces si el bloque finally se ejecutase solo despu茅s de una excepci贸n, el mismo c贸digo de limpieza tendr铆a que estar presente dentro y fuera del bloque finally, y por lo tanto no hay raz贸n para no tener el bloque finally solo, y dejarlo ejecutarse sin importar si hay excepciones o no.

El siguiente ejemplo abre un archivo y despues ejecuta sentencias que usan el archivo (JavaScript del lado del servidor permite acceder a archivos). Si una excepci贸n es lanzada mientras el archivo est谩 abierto, la cl谩usula finally cierra el archivo antes de que el script falle. El c贸digo en finally tambi茅n se ejecuta despu茅s de un retorno expl铆cito de los bloques try o catch.

openMyFile()
try {
   // retiene un recurso
   writeMyFile(theData);
}
finally {
   closeMyFile(); // siempre cierra el recurso
}

Ejemplos

Bloques try anidados

Primero, veamos que pasa con esto:

try {
  try {
    throw new Error('oops');
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "finally"
// "outer" "oops"

Ahora, si nosotros ya capturamos la excepci贸n en una declaraci贸n try interna agregando un bloque catch.

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"

Y ahora vamos a relanzar el error.

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
    throw ex;
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"
// "outer" "oops"

Cualquier excepci贸n dad ser谩 capturada solo una vez por el bloque catch m谩s cercano a menos que sea relanzado. Por supuesto cualquier nueva excepci贸n que se origine en el bloque 'interno' (porque el c贸digo en el bloque catch puede hacer algo que lanze un error), ser谩 capturado por el bloque 'externo'.

Retornando de un bloque finally

Si el bloque finally retorna un valor, este valor se convierte en el valor de retorno de toda la producci贸n try-catch-finally, a pesar de cualquier sentencia return en los bloques try y catch. Esto incluye excepciones lanzadas dentro del bloque catch.

(function() {
  try {
    try {
      throw new Error('oops');
    }
    catch (ex) {
      console.error('inner', ex.message);
      throw ex;
    }
    finally {
      console.log('finally');
      return;
    }
  }
  catch (ex) {
    console.error('outer', ex.message);
  }
})();

// Output:
// "inner" "oops"
// "finally"

El "oops" externo no es lanzado debido al retorno en el bloque finally. Lo mismo aplicar铆a para cualquier valor retornado del bloque catch.

Vea los ejemplos para throw.

Vea tambi茅n