Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

patrones:excepciones [2012/09/27 09:59]
admin [Mas problemas]
patrones:excepciones [2016/07/03 20:02] (actual)
Línea 104: Línea 104:
 <note important> <note important>
 La Checked Exceptions forman parte del flujo lógico de nuestro programa y al programar debemos tenerlas en cuenta y tratarlas adecuadamente no viéndolas como un problema del que debemos deshacernos. La Checked Exceptions forman parte del flujo lógico de nuestro programa y al programar debemos tenerlas en cuenta y tratarlas adecuadamente no viéndolas como un problema del que debemos deshacernos.
-</note> 
- 
-<note warning> 
-Lo que nunca se debe hacer con una Checked Exception es imprimir la traza del error y/o seguir con la ejecución. Si la forma correcta de tratar excepción es //no hacer nada//, ¿para que imprimes la traza? y si hay que hacer algo con el excepción ¿era necesario imprimir la traza?. 
- 
-Así que los siguientes trozos de código son erroneos: 
-<code java 1> 
-try { 
-    double c=matematicas.dividir(-1.6, 0); 
-} catch (Exception ex) { 
-    //Ignorar la excepción 
-} 
-</code> 
- 
-<code java 1> 
-try { 
-    double c=matematicas.dividir(-1.6, 0); 
-} catch (Exception ex) { 
-    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
-} 
-</code> 
- 
-<code java 1> 
-try { 
-    double c=matematicas.dividir(-1.6, 0); 
-} catch (Exception ex) { 
-    ex.printStackTrace(); 
-} 
-</code> 
- 
 </note> </note>
  
Línea 144: Línea 114:
 Por ejemplo en el caso anterior de la división por cero, es un error de programación que alguien nos pase como dividendo un cero, en ese caso lanzaremos un <javadoc>java.lang.RuntimeException|RuntimeException</javadoc>. Por ejemplo en el caso anterior de la división por cero, es un error de programación que alguien nos pase como dividendo un cero, en ese caso lanzaremos un <javadoc>java.lang.RuntimeException|RuntimeException</javadoc>.
  
-Al ser las unchecked Exceptions errores en el programa , poco podemos hacer por arreglarlas. Por ello no es obligatorio tratarlas con un ''try-catch''. Lo único que podemos hacer en la mayoría de casos es hacer que el programa acabe fallando y que se muestre un mensaje de error al usuario. Es decir, si el programa funciona mal , es mejor que no siga funcionando antes que hacer que continúe funcionado pero usando datos erróneos, ya que ne ese caso los resultados que generara también podrían ser erróneos.+Al ser las unchecked Exceptions errores en el programa , poco podemos hacer por arreglarlas. Por ello no es obligatorio tratarlas con un ''try-catch''. Lo único que podemos hacer en la mayoría de casos es hacer que el programa acabe fallando y que se muestre un mensaje de error al usuario. Es decir, si el programa funciona mal , es mejor que no siga funcionando antes que hacer que continúe funcionado pero usando datos erróneos, ya que en ese caso los resultados que generara también podrían ser erróneos.
  
 <note important> <note important>
Línea 199: Línea 169:
 La solución a este problema consiste simplemente en leerse la documentación para ver cuando se lanza una excepción unchecked , que debería haber sido Checked, para capturarla y hacer el correcto tratamiento con ella. La solución a este problema consiste simplemente en leerse la documentación para ver cuando se lanza una excepción unchecked , que debería haber sido Checked, para capturarla y hacer el correcto tratamiento con ella.
  
-Mas información sobre la excepción <javadoc jee6>javax.validation.ConstraintViolationException|ConstraintViolationException</javadoc> y como solucionar el problema lo tenemos en [[unidades:07_arquitectura:03_excepciones]]+Mas información sobre la excepción <javadoc jee6>javax.validation.ConstraintViolationException|ConstraintViolationException</javadoc> y como solucionar el problema lo tenemos en [[unidades:07_arquitectura:02_excepciones]]
 ===== Formas erróneas de tratar las excepciones ===== ===== Formas erróneas de tratar las excepciones =====
 Veamos ahora una serie de errores que se cometen al tratar las excepciones. Veamos ahora una serie de errores que se cometen al tratar las excepciones.
Línea 222: Línea 192:
  
 ==== Crear una excepción inutil ==== ==== Crear una excepción inutil ====
-Otro segundo error es crear una nueva excepción que no aporta nada respecto a ''RuntimeException'' y usarla en vez de ''RuntimeException''+Otro segundo error es crear una nueva excepción **generica** (( No me refiero a excepciones concretas que tienen significado específico como ''NullPointerException'' )) que no aporta nada respecto a ''RuntimeException'' (( Lo mismo se aplica a Exception )) y usarla en vez de ''RuntimeException''
  
 <code java 1> <code java 1>
Línea 245: Línea 215:
  
 ==== Pasar el problema hacia arriba ==== ==== Pasar el problema hacia arriba ====
-La última forma errónea de tratar la excepciones es simplemente hacer que el método superior a su vez declare que lanza esas excepciones checked pero que deberían haber sido uncheked. Con ésto lo único que hacemos es expandir el problema hacia arriba sin solucionarlo.+La siguiente forma errónea de tratar la excepciones es simplemente hacer que el método superior a su vez declare que lanza esas excepciones checked pero que deberían haber sido uncheked. Con ésto lo único que hacemos es expandir el problema hacia arriba sin solucionarlo.
  
 <code java 1> <code java 1>
Línea 265: Línea 235:
 try { try {
     double c=matematicas.dividir(-1.6, 0);     double c=matematicas.dividir(-1.6, 0);
-} catch (RuntimeException ex) { +} catch (Exception ex) { 
-    //Ignorar la excepción+
 } }
 </code> </code>
 +
 +
 +Vemos en la línea 4 como no se realiza ninguna acción al capturar la excepción, por lo tanto la ejecución seguirá como si no hubiera pasado nada.
 +
 +==== Log ====
 +Acabamos de ver en el apartado anterior que nunca (( Siempre hay //excepciones// para todo )) se debe ignorar la excepción. Una forma de ignorarla pero que aparenta ser mejor solución es guardar en el log la excepción que se ha producido pero sin hacer nada mas.
  
 <code java 1> <code java 1>
Línea 277: Línea 253:
 } }
 </code> </code>
 +
 +En la línea 4 guardamos en el log la excepción pero el programa sigue ejecutándose. Como ya hemos comentado no debería seguir la ejecución del programa puesto que los datos pueden haber quedado en un estado erróneo.
 +
 +La idea de guardar en el log la excepción es buena por si misma. Sin embargo no suele ser necesario guardarla explícitamente ya que en muchas ocasiones ya se guarda automáticamente. Por ejemplo en aplicaciones Web , el propio contenedor al detectar ((Siempre que no la detengamos antes )) una excepción guardará en el log la excepción que se ha producido.
 +
 +==== Consola  ====
 +Otra forma erronea de guardar las excepciones consiste en mostrar la traza del error por la consola.
  
 <code java 1> <code java 1>
Línea 286: Línea 269:
 </code> </code>
  
-En los 3 casos estamos ignorando la excepción aunque en los 2 últimos dejemos una //bonita// traza del error. ¡El problema es que sigue ejecutándose el programa!+En la línea 4 mostramos por la consola la traza de la excepción pero el programa sigue ejecutándose. Como ya se ha dicho no debería seguir la ejecución del programa puesto que los datos pueden haber quedado en un estado erróneo.
  
-==== Trazas ==== +En aplicaciones Web o aplicaciones de Ventanas , esta opción tiene menos sentido aun que la opción del log, ya que guardando la traza en un fichero de log está mucho más accesible para poder averiguar el origen del problema que mostrándolo por consola ya que la consola la puede cerrar el usuario y perder toda la traza o simplemente que no tengamos acceso a la consola.
-Acabamos de ver en el apartado anterior como aun ignorando la excepción se guardaban (( en el log por consola )) la traza de la excepción. Normalmente no es necesario guardar explícitamente la excepción.+
  
-En aplicaciones Web no suele ser necesario guardar en el log la excepción ya que lo suele hacer automáticamente el servidor de aplicaciones.+==== Imprimirla ==== 
 +Por último pero no por ello menos usada está la //técnica// de imprimir el mensaje de la excepción
 + 
 +<code java 1> 
 +try { 
 +    double c=matematicas.dividir(-1.6, 0); 
 +} catch (RuntimeException ex) { 
 +    System.out.println("Falló al dividir"); 
 +
 +</code> 
 + 
 +Esta forma tiene los mismos problemas del anterior de imprimirla por consola pero ésta es aun peor, hemos perdido toda la información de la excepción.
  
 ===== Mejoras en el tratamiento de excepciones ===== ===== Mejoras en el tratamiento de excepciones =====
Línea 383: Línea 376:
 Es decir que ahora la traza para una ''RuntimeException'' es como debería ser ,ya que no queda encapsulada por ninguna otra excepción. Es decir que ahora la traza para una ''RuntimeException'' es como debería ser ,ya que no queda encapsulada por ninguna otra excepción.
  
 +<note tip>
 +Por los ejemplos puede parecer un poco exagerado querer que no se encapsulen las excepciones pero pongo aquí un ejemplo de excepciones en Hibernate:
 +
 +  Exception in thread "main" org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
 +  at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:185)
 +  at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135)
 +  at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:367)
 +  at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1740)
 +  at curshibernatet03e01.CursHibernateT03E01.main(CursHibernateT03E01.java:23)
 +  Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]
 +  at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:138)
 +  at org.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer(EntityTuplizerFactory.java:188)
 +  at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:341)
 +  at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:502)
 +  at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:144)
 +  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 +  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
 +  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 +  at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
 +  at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163)
 +  ... 4 more
 +  Caused by: java.lang.reflect.InvocationTargetException
 +  at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
 +  at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
 +  at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
 +  at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
 +  at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:135)
 +  ... 13 more
 +  Caused by: org.hibernate.PropertyNotFoundException: Could not find a getter for domicilio in class curshibernatet03e01.Cliente
 +  at org.hibernate.property.BasicPropertyAccessor.createGetter(BasicPropertyAccessor.java:316)
 +  at org.hibernate.property.BasicPropertyAccessor.getGetter(BasicPropertyAccessor.java:310)
 +  at org.hibernate.mapping.Property.getGetter(Property.java:320)
 +  at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertyGetter(PojoEntityTuplizer.java:436)
 +  at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:200)
 +  at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:82)
 +  ... 18 more
 +  
 +Realmente la información mas útil la encontramos justamente en la primera excepción que se produce. Sin embargo está justamente al final de toda la traza: 
 +
 +  PropertyNotFoundException: Could not find a getter for domicilio in class curshibernatet03e01.Cliente
 +  
 +Así que si no se hubiera encapsulado la excepción se vería en la primera línea en vez de ir a buscarla al final de la traza.
 +
 +</note>
 ==== La solución definitiva ==== ==== La solución definitiva ====
 La solución definitiva es que las excepciones checked tenga también una traza //limpia// como las unchecked. Antes hemos comentado que es imposible pero hay un truco en Java que permite hacerlo, no voy a explicar como funciona el truco simplemente voy a explicar como hacerlo. La solución definitiva es que las excepciones checked tenga también una traza //limpia// como las unchecked. Antes hemos comentado que es imposible pero hay un truco en Java que permite hacerlo, no voy a explicar como funciona el truco simplemente voy a explicar como hacerlo.
Línea 428: Línea 465:
  
 Por fin con este ultimo truco hemos conseguido simplificar la traza con todas las excepciones. Por fin con este ultimo truco hemos conseguido simplificar la traza con todas las excepciones.
- 
-<note> 
-Puede parecer un poco exagerado querer limpiar la traza para dejarla mas clara , pero en programas muy extensos se acumulan muchas excepciones dentro de otras excepciones y al final queda poco claro que ha ocurrido viendo la traza. 
- 
-Pero si no quieres complicar el código, usa simplemente la solución anterior a ésta que queda todo más estándar. 
-</note> 
  
 ===== Referencias ===== ===== Referencias =====
Línea 442: Línea 473:
   * [[http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html|The Java Tutorials.Unchecked Exceptions—The Controversy]]   * [[http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html|The Java Tutorials.Unchecked Exceptions—The Controversy]]
   * [[http://www.gamlor.info/wordpress/2010/02/throwing-checked-excpetions-like-unchecked-exceptions-in-java/|Throwing Checked Exceptions Like Unchecked Exceptions in Java]]   * [[http://www.gamlor.info/wordpress/2010/02/throwing-checked-excpetions-like-unchecked-exceptions-in-java/|Throwing Checked Exceptions Like Unchecked Exceptions in Java]]
 +  * [[http://www.manageability.org/blog/stuff/exceptional-exception-handling-techniques|13 Exceptional Exception Handling Techniques]]
patrones/excepciones.1348732760.txt.gz · Última modificación: 2016/07/03 20:20 (editor externo)
Ir hasta arriba
CC Attribution-Noncommercial-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0