## Manejar Mensajes de Excepciones Codificados Internamente

Supongamos que llamamos a un método que lanza una excepción, y queremos mostrar el mensaje de la excepción cuando ocurra el error. Si este método pertenece a una clase de un paquete escrito por otras personas, no tendremos ningún control sobre el texto del mensaje a menos que tengamos acceso al código fuente. Este puede ser un grave problema si el texto del mensaje ha sido codificado, porque no podrá ser traducido a otros idiomas. En el siguiente código de ejemplo, encontramos este problema cuando abrimos un fichero que no existe:

    static public void defaultMessage() {

       try {
          FileInputStream in = new FileInputStream("vapor.txt");
       }
       catch (FileNotFoundException e) {
          System.out.println("e.getMessage = " + e.getMessage());
          System.out.println("e.getLocalizedMessage = " + e.getLocalizedMessage());
          System.out.println("e.toString = " + e.toString());
       }
    }

La clausula Catch del método defaultMessage genera la siguiente salida:

    e.getMessage = vapor.txt
    e.getLocalizedMessage = vapor.txt
    e.toString = java.io.FileNotFoundException: vapor.txt

Estos mensajes son inadecuados por varias razones. Primero, el texto del mensaje está codificado dentro de la clase FileNotFoundException y no puede ser localizado. Intentamos imprimir el String devuelto por getLocalizedMessage, pero como getLocalizedMessage no ha sido implementada, sólo devuelve el mismo mensaje que el método getMessage. Además, getMessage sólo devuelve el nombre del fichero, que por sí mismo no es un mensaje traducible. Aunque podríamos encontrar útil el tener el nombre del fichero durante la depuración, nuestros usuarios finales necesitarán un mensaje más informativo.

En general, los mensajes proporcionados por subclases de Exception, como FileNotFoundException, se han creado para programadores, no para usuarios finales. Por ejemplo, un procesador de textos no debería mostrar, "java.io.FileNotFoundException: vapor.txt," cuando el usuario trata de abrir un fichero que no existe. Este mensaje, aunque es técnicamente correcto, no tiene sentido para la mayoría de la gente. En su lugar, cuando el procesador de textos capturara la FileNotFoundException, debería mostrar este mensaje: "Cannot find the file named vapor.txt. Make sure the file exists."

En una aplicación como un procesador de textos, el texto devuelto por FileNotFoundException.getMessage no es apropiado para los usuarios finales. Deberíamos proporcionar un mensaje que sea fácil de entender, y que pueda ser traducido. Veremos como hacer esto con el siguiente ejemplo.

Como el texto del mensaje necesita se traducido, lo aislaremos en un ResourceBundle. Almacenaremos nuestros mensajes en un fichero de propiedades, construiremos un ResourceBundle llamado ExceptionBundle. Aquí tenemos el mensaje del fichero ExceptionBundle_en_US.properties:

    template = Cannot find the file named {0}.  Make sure the file exists.

En el siguiente código mostramos un mensaje sensible a la localidad cuando se captura FileNotFoundException. Primero creamos un ResourceBundle para la Localidad apropiada. Luego recuperamos el patrón del mensaje traducido desde el ResourceBundle. Finalmente, aplicamos el patrón del formato para insertar el nombre del fichero en el mensaje:

    static public void customMessage(Locale currentLocale) {

       System.out.println("Locale: " + currentLocale.toString());
       String fileName = "vapor.txt";

       try {
          FileInputStream in = new FileInputStream(fileName);
       }
       catch (FileNotFoundException e) {
          ResourceBundle messages =
              ResourceBundle.getBundle("ExceptionBundle",currentLocale);
          Object[] messageArguments = {fileName};
          MessageFormat formatter = new MessageFormat("");
          formatter.setLocale(currentLocale);
          formatter.applyPattern(messages.getString("template"));
          String errorOut = formatter.format(messageArguments);
          System.out.println(errorOut);
       }
    }

La salida del método customMessage está bastante mejor que: "java.io.FileNotFoundException: vapor.txt."

    Locale: en_US
    Cannot find the file named vapor.txt.  Make sure the file exists.

    Locale: de_DE
    Die Datei vapor.txt konnte nicht gefunden werden.
    Stellen Sie sicher, daß die Datei existiert.

Ozito