Fork me on GitHub

Exception Handling Tutorial

This tutorial demonstrates the ease in handling exceptions within an WoOF web application.

The tutorial will demonstrate this by a template method throwing an exception that is handled by writing the exception to stderr. Though this is a simple example it does demonstrate the ease of handling exceptions.

This tutorial also introduces the @Parameter annotation to allow passing an object between methods.

Download Tutorial Source

Template throwing exception

The following is the template:

<html>
    <form action="#{submit}">
        <input type="submit" />
    </form>
</html>

with the logic throwing the exception:

public class TemplateLogic {

	public void submit() throws Exception {
		throw new SQLException("Test");
	}

}

Pressing the submit button will trigger the exception to be thrown.

The tutorial will demonstrate the ease in which this exception can be handled.

Exception handling configuration

The following shows the configuration for handling the above template exception.

ExceptionHttpServer screen shot.

The exception being handled is an SQLException. To add the exception right click and add exception.

The exception is linked to the Handler. The Handler is the following POJO. It is added as a class section (right click and add section).

public class ExceptionHandler {

	@NextTask("TechnicalFault")
	public void handleSqlException(@Parameter SQLException ex) {
		// Production code may take some action and would use a Logger
		System.err.println(ex.getMessage());
	}

}

As per the configuration above, the handleSqlException method is invoked to handle the SQLException.

Once the method completes it follows normal WoOF behaviour. In other words, the @NextTask annotation is honoured resulting in the static error page being sent to the client.

@Parameter

The @Parameter annotation identifies a value to be passed from the previous task.

The handling of an exception is actually via OfficeFloor functionality. The exception is caught by WoOF and passed as a parameter to the configured task. In this case, the handleSqlException(...) method.

The @Parameter annotation can also be used to obtain the value from the following:

  • receive the exception being handled (as in above example)
  • return value from the previous method
  • parameter to a @FlowInterface method

This functionality is useful and provided by the underlying OfficeFloor framework. However, within WoOF the necessity to pass parameters is used typically only for exception handling. The use of dependency injected objects is typically a better way to pass state between methods (i.e. HttpRequestStateful).

Resource

The remaining configuration indicates that the TechnicalFault should send the following static response.

<html>
	<body>
		<p>Technical error has occurred.</p>
	</body>
</html>

It is possible to use the details of the exception within a template to generate a response. For simplicity of this tutorial however a static resource is used (right click and add resource).

Template specific exception handling

For exceptions specific to the template, the template logic class may provide a method with a parameter of the exception type that is annotated with @Parameter. WoOF will reflectively interrogate the template logic class for these methods and use them for exception handling before escalating to the application.woof configuration.

In other words, the handleSqlException(...) method can be moved to the TemplateLogic class to provide specific handling of SQLExceptions occurring within the template.

Unit Test

The following unit test shows the exception handling by listening in on stderr to ensure the exception message is written to it:

	public void testExceptionHandling() throws Exception {

		// Override stderr
		ByteArrayOutputStream error = new ByteArrayOutputStream();
		System.setErr(new PrintStream(error, true));

		// Start server
		WoofOfficeFloorSource.start();
		
		// Clear setup log
		error.reset();

		// Submit to trigger the exception
		this.client.execute(new HttpGet(
				"http://localhost:7878/template-submit.woof"));

		// Ensure handling by logging the failure
		String log = new String(error.toByteArray()).trim();
		assertEquals("Should log error", "Test", log);
	}

Next

The next tutorial looks at rendering generated HTML.