Diferencias

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

Enlace a la vista de comparación

patrones:excepciones [2012/09/27 10:02]
admin [Ignorarla]
patrones:excepciones [2016/07/03 20:02] (actual)
Línea 114: 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 169: 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 192: 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 215: 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 243: Línea 243:
 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. 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.
  
-==== Trazas ==== +==== Log ==== 
-Acabamos de ver en el apartado anterior como aun ignorando la excepción se guardaban (( en el log o por consola )) la traza de la excepción. Normalmente no es necesario guardar explícitamente la excepción.+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.
  
-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.+<code java 1> 
 +try { 
 +    double c=matematicas.dividir(-1.6, 0); 
 +} catch (RuntimeException ex) { 
 +    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
 +
 +</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> 
 +try { 
 +    double c=matematicas.dividir(-1.6, 0); 
 +} catch (RuntimeException ex) { 
 +    ex.printStackTrace(); 
 +
 +</code> 
 + 
 +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. 
 + 
 +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. 
 + 
 +==== 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 338: 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 383: 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 397: 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.1348732959.txt.gz · Última modificación: 2016/07/03 20:18 (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