viernes, 6 de julio de 2007

¿Por qué la gente hace e.printStackTrace() en vez de relanzar como RuntimeException?

¿No les pasó de ver código similar a este?
try {
    InputStream input = new FileInputStream("myFile.txt");
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
Seguro que sí. Desde verlo en ejemplos en libros de texto (porque "total, es un ejemplo, se entiende que no es lo correcto") hasta en códigos de programas reales. ¡Pero si hasta eclipse autogenera ese try-catch!

Es una porquería. No sirve para nada y oculta bugs. La razón más común por la que se lo hace creo que es porque no se quiere manejar la excepción. Esto puede ser porque ese error nunca ocurre, porque no quiero que mi método tenga que tener un throws, o por desconocimiento, no se.

La forma correcta es esta:
try {
    InputStream input = new FileInputStream("myFile.txt");
} catch (FileNotFoundException e) {
    e.printStackTrace(); // esto es opcional, obviamente
    throw new RuntimeException(e);
}
De esta manera, al relanzar la excepción como RuntimeException nuestro método no tiene que declarar throws FileNotFoundException (para este ejemplo, claro está) y si el error ocurre lo vamos a ver enseguida porque nuestra aplicación va a fallar con un hermoso stack trace.

Podemos hacer que eclipse nos ayude con esto, modificando el code template. Vamos a Windows->Preferences->Java->Code Style->Code Templates y buscamos el que se llama Catch Block Body.

El valor por default es:
// ${todo} Auto-generated catch block
${exception_var}.printStackTrace();
Yo sugiero cambiarlo a:
${exception_var}.printStackTrace();
throw new RuntimeException(${exception_var});

Ah, de paso les comento, con respecto a lo que comenté hace un tiempo, que ya salió el Eclipse Europa.

Disfruten!

3 comentarios:

Pablo Frias dijo...

El printStackTrace está bueno cuando hacés debug, pero me parece que el error es no sacarlo cuando el SW ya está en producción.

El otro problema con las excepiones es ¿qué pasa cuando no se hace nada?, es decir, cuando se tiene el catch completamente vacio.
Justo estaba leyendo un articulo
bastante interesante que plantea una comparación entre la forma de manejar excepciones en Java y otros lenguajes y trata este tipo de problemas.

Saludos

Diego dijo...

Cuánto hace que no veia código en Java!! Qué nostalgía :)

G J Ortega dijo...

Woooow, ahora todo tiene sentido, yo lo hacía pero bueno estoy aprendiendo y me has enseñado una valiosa lección, mal hábito de programación desechado. Saludos