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!