Groovy - Manejo de excepciones

Se requiere el manejo de excepciones en cualquier lenguaje de programación para manejar los errores de tiempo de ejecución de modo que se pueda mantener el flujo normal de la aplicación.

La excepción normalmente interrumpe el flujo normal de la aplicación, razón por la cual necesitamos utilizar el manejo de excepciones en nuestra aplicación.

Las excepciones se clasifican ampliamente en las siguientes categorías:

  • Checked Exception - Las clases que extienden la clase Throwable excepto RuntimeException y Error se conocen como excepciones comprobadas, p. Ej., IOException, SQLException, etc. Las excepciones marcadas se comprueban en tiempo de compilación.

Un caso clásico es FileNotFoundException. Suponga que tiene el siguiente código en su aplicación que lee de un archivo en la unidad E.

class Example {
   static void main(String[] args) {
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file);
   } 
}

si el archivo (file.txt) no está en la unidad E, se generará la siguiente excepción.

Capturado: java.io.FileNotFoundException: E: \ file.txt (El sistema no puede encontrar el archivo especificado).

java.io.FileNotFoundException: E: \ file.txt (El sistema no puede encontrar el archivo especificado).

  • Unchecked Exception - Las clases que extienden RuntimeException se conocen como excepciones no comprobadas, por ejemplo, ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, etc. Las excepciones no comprobadas no se comprueban en tiempo de compilación, sino que se comprueban en tiempo de ejecución.

Un caso clásico es la excepción ArrayIndexOutOfBoundsException, que ocurre cuando intenta acceder a un índice de una matriz que es mayor que la longitud de la matriz. A continuación se muestra un ejemplo típico de este tipo de error.

class Example {
   static void main(String[] args) {
      def arr = new int[3];
      arr[5] = 5;
   } 
}

Cuando se ejecuta el código anterior, se generará la siguiente excepción.

Atrapado: java.lang.ArrayIndexOutOfBoundsException: 5

java.lang.ArrayIndexOutOfBoundsException: 5

  • Error - El error es irrecuperable, por ejemplo, OutOfMemoryError, VirtualMachineError, AssertionError, etc.

Estos son errores de los que el programa nunca puede recuperarse y harán que el programa se bloquee.

El siguiente diagrama muestra cómo está organizada la jerarquía de excepciones en Groovy. Todo se basa en la jerarquía definida en Java.

Captura de excepciones

Un método detecta una excepción utilizando una combinación de try y catchpalabras clave. Se coloca un bloque try / catch alrededor del código que podría generar una excepción.

try { 
   //Protected code 
} catch(ExceptionName e1) {
   //Catch block 
}

Todo su código que podría generar una excepción se coloca en el bloque de código protegido.

En el bloque de captura, puede escribir código personalizado para manejar su excepción para que la aplicación pueda recuperarse de la excepción.

Veamos un ejemplo del código similar que vimos anteriormente para acceder a una matriz con un valor de índice que es mayor que el tamaño de la matriz. Pero esta vez envolvemos nuestro código en un bloque try / catch.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      } catch(Exception ex) {
         println("Catching the exception");
      }
		
      println("Let's move on after the exception");
   }
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

Catching the exception 
Let's move on after the exception

Del código anterior, terminamos el código defectuoso en el bloque try. En el bloque de captura, solo capturamos nuestra excepción y emitimos un mensaje de que se ha producido una excepción.

Múltiples bloques de captura

Uno puede tener múltiples bloques de captura para manejar múltiples tipos de excepciones. Para cada bloque de captura, dependiendo del tipo de excepción generada, escribiría código para manejarlo en consecuencia.

Modifiquemos nuestro código anterior para capturar la excepción ArrayIndexOutOfBoundsException específicamente. A continuación se muestra el fragmento de código.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      }catch(ArrayIndexOutOfBoundsException ex) {
         println("Catching the Array out of Bounds exception");
      }catch(Exception ex) {
         println("Catching the exception");
      }
		
      println("Let's move on after the exception");
   } 
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

Catching the Aray out of Bounds exception 
Let's move on after the exception

En el código anterior, puede ver que el bloque de captura ArrayIndexOutOfBoundsException se captura primero porque significa los criterios de la excepción.

Finalmente bloquear

los finallyEl bloque sigue a un bloque try o un bloque catch. Un último bloque de código siempre se ejecuta, independientemente de la ocurrencia de una excepción.

El uso de un bloque finalmente le permite ejecutar cualquier declaración de tipo limpieza que desee ejecutar, sin importar lo que suceda en el código protegido. La sintaxis de este bloque se proporciona a continuación.

try { 
   //Protected code 
} catch(ExceptionType1 e1) { 
   //Catch block 
} catch(ExceptionType2 e2) { 
   //Catch block 
} catch(ExceptionType3 e3) { 
   //Catch block 
} finally {
   //The finally block always executes. 
}

Modifiquemos nuestro código anterior y agreguemos el bloque de código finalmente. A continuación se muestra el fragmento de código.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      } catch(ArrayIndexOutOfBoundsException ex) {
         println("Catching the Array out of Bounds exception");
      }catch(Exception ex) {
         println("Catching the exception");
      } finally {
         println("The final block");
      }
		
      println("Let's move on after the exception");
   } 
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

Catching the Array out of Bounds exception 
The final block 
Let's move on after the exception

Los siguientes son los métodos de excepción disponibles en Groovy:

public String getMessage ()

Devuelve un mensaje detallado sobre la excepción que se ha producido. Este mensaje se inicializa en el constructor Throwable.

public Throwable getCause ()

Devuelve la causa de la excepción representada por un objeto Throwable.

cadena pública toString ()

Devuelve el nombre de la clase concatenada con el resultado de getMessage ()

public void printStackTrace ()

Imprime el resultado de toString () junto con el seguimiento de la pila en System.err, el flujo de salida del error.

public StackTraceElement [] getStackTrace ()

Devuelve una matriz que contiene cada elemento del seguimiento de la pila. El elemento en el índice 0 representa la parte superior de la pila de llamadas y el último elemento de la matriz representa el método en la parte inferior de la pila de llamadas.

public Throwable fillInStackTrace ()

Rellena el seguimiento de la pila de este objeto Throwable con el seguimiento de la pila actual, agregando a cualquier información anterior en el seguimiento de la pila.

Ejemplo

A continuación se muestra el ejemplo de código utilizando algunos de los métodos dados anteriormente:

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      }catch(ArrayIndexOutOfBoundsException ex) {
         println(ex.toString());
         println(ex.getMessage());
         println(ex.getStackTrace());  
      } catch(Exception ex) {
         println("Catching the exception");
      }finally {
         println("The final block");
      }
		
      println("Let's move on after the exception");
   } 
}

Cuando ejecutamos el programa anterior, obtendremos el siguiente resultado:

java.lang.ArrayIndexOutOfBoundsException: 5 
5 
[org.codehaus.groovy.runtime.dgmimpl.arrays.IntegerArrayPutAtMetaMethod$MyPojoMetaMet 
hodSite.call(IntegerArrayPutAtMetaMethod.java:75), 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) ,
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) ,
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) ,
Example.main(Sample:8), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93),
groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325),
groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1443),
org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:893),
groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:287),
groovy.lang.GroovyShell.run(GroovyShell.java:524),
groovy.lang.GroovyShell.run(GroovyShell.java:513),
groovy.ui.GroovyMain.processOnce(GroovyMain.java:652),
groovy.ui.GroovyMain.run(GroovyMain.java:384),
groovy.ui.GroovyMain.process(GroovyMain.java:370),
groovy.ui.GroovyMain.processArgs(GroovyMain.java:129),
groovy.ui.GroovyMain.main(GroovyMain.java:109),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:109),
org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:131),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)]
 
The final block 
Let's move on after the exception