As was implied in the previous examples, each exception instance can a have pieces of information related to the exception. The most typical is the name of a file. The information will become the building blocks for creating a message to the user.Since we don’t have time learning a new UI framework, let’s consider a command line program that shows messages on the console. See how the messages for System.err.println() are constructed using the information in the exception instances.

    public static void main(String[] args) {
	if (args.length != 1) {
	    System.err.println("java MakeFile <filename>");
	    System.exit(-1);
	}

	String filename = args[0];

	MakeFile instance = new MakeFile();

	try {
	    instance.saveToFile(filename);
	} catch (RecoveredException_IllegalStorageManipulation c_exception) {
	    System.err.println("ERROR: The following file was manipulated and caused execution to stop: " + c_exception.getAbsolutePathOfFileCausingException());
	    System.exit(-1);
	} catch (RecoveredException_CannotWriteToFile c_exception) {
	    System.err.println("ERROR: Could not write to the following temporary file: " + c_exception.getAbsolutePathOfFileCausingException());
	    System.exit(-1);
	} catch (RecoveredException_IO c_exception) {
	    System.err.println("ERROR: Could not create file, because of I/O error: " + c_exception.getAbsolutePathsOfFilesCausingException());
	    System.exit(-1);
	} catch (RecoveredException_CannotWriteToDirectory c_exception) {
	    System.err.println("ERROR: Cannot write to a directory: " + c_exception.getAbsolutePathOfDirectoryCausingException());
	    System.exit(-1);
	} catch (UnrecoveredException_IO c_exception) {
	    System.err.println("ERROR: Could not complete request due to an I/O error. The following files may have been affected: " + c_exception.getAbsolutePathsOfFilesCausingException());
	    System.exit(-1);
	}
    }

When you see the example above, you would probably realize that this is where internationalization should come into play. This is not an article about internationalization, so I’ll only briefly explain my view on this.

Java has a getLocalizedMessage() for all its exceptions (Throwable). This is supposed to allow translation of error messages for each exception. Because only a few exceptions get to become messages on the UI, it would be a waste of time to translate all these exception messages.

getLocalizedMessage() also tends to be impractical because there is not enough context to explain the exception at the location it is raised. For instance, the write() function of the java.io.FileOutputStream class has no idea what kind of file it is writing to, so the message string for the exception that it throws cannot mention it in any meaningful way. On the other hand, the function that processes the request from the user has such information.

Outsourcing the translation of short messages tends to produce very poor results. Time should be spent choosing only the strings that show up on the UI, and more time should be spent explaining them to the translator. As was shown above, these messages belong to the Presentation layer and not in the exception.

Contents

Background

Review of Exception Handling Basics

The Requirements

The Three-tiered Exception Handling Architecture

Summary