Skip to content


The BusinessException pattern

This exception is probably one of the most common home-made exceptions, one that pops up in almost every project. I’ll try and show you how it works and what the advantages are.

One of the “problems” of doing all the business logic in the Service (or UseCase, Business) Layer is getting the right exception message back onto the screen. Lot’s of times people invent all kinds of home-brewed exceptions: e.g. ResultNotFoundException, InsufficientFundsException, DateTooFarIntoFutureException, …
Another approach, which is far worse, is to let specialized exceptions like a ConstraintViolation (hibernate), UserException (axis) and many others. It couples the front-end to back end.

When defining custom exceptions for every problem, you force the controller to catch all the exceptions that could be thrown separately. Adding a new exception can be cumbersome, and it does not really matter if you define them as checked or unchecked, unless you plan to catch the remaining exceptions with a generic info message like: something went wrong…

What’s the correct solution?

Here comes the BusinessException

public class BusinessException
    extends RuntimeException {
	/** A code indicating the cause of
            the exception. */
	private String code;
	/** The exception that is wrapped by
            the business component. */
	private Exception wrappedException;
	/**
	 * Constructor.
	 *
	 * @param code The code indicating the
         * cause of the exception.
	 * @param wrappedException The exception
         * that is wrapped by the business
         * component.
	 */
	public BusinessException(String code,
          Exception wrappedException) {
		this.code = code;
		this.wrappedException =
                  wrappedException;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public Exception getWrappedException() {
		return wrappedException;
	}
	public void setWrappedException(
           Exception wrappedException) {
		this.wrappedException = wrappedException;
	}
}

When a business rule validation has been detected, a new BusinessException should be throw.

When an exception is thrown from any layer beneath the Controller layer, it should be wrapped by the BusinessException.

The code is the key for translation by the view renderer.

Placing this in the architecture

When we place the BusinessException into a widely use architectural stack we come up with something like this:

Advantages

The advantages are clear:

  • The controller and other layers are loosely coupled (e.g. no DAO dependency in Controller)
  • The transaction can be rolled back, since the exception is thrown.
  • The controllers aren’t forced to catch many exceptions.
  • No need for those custom made exceptions. One exception to rule them all!

BusinessException versus other exceptions

The businessException should wrap a recoverable violation or exception, that can be displayed in the screen. Transaction is rolled back, and the user can change the input and/or try again.

Normal exceptions are unrecoverable. The transaction is rolled back, and the user is directed to an error page.

It’s not the point to wrap every exception, but only the expected ones. Don’t wrap a It’s a really simple pattern, but a very powerful one.

In essence 4 scenario’s can happen:

  1. The first level fails. Typically this is something like a missing required field. The user is redirected to the same page to fix the problem.
  2. The second validation fails: a business exception is thrown.  Typically this is a business rule that failed, for instance a balance is too low to complete a purchase. It also could be an exception wrapped by the BusinessException. For instance when the database row has changed after you loaded it.
  3. Everything succeeded, the business layer returned normally.
  4. The business layer threw an exception (not a BusinessException), the page is redirected to the error page. Unrecoverable, should only be on programming bug.

Conclusion

A lot has to be said for straight and simple win-win patterns. This one is definately one of those.

Posted in architecture, Java.

Tagged with , .


7 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. sun007 says

    Hi,
    Great post.Can you please show some sample code how you use BusinessException.

  2. Johan Vosloo says

    Two questions:

    1. Presumably the code property is used to look up a matching key to a user message, in something like an ApplicationResources.properties file?

    2. Assuming the 1st approach is used, how would you present more informative error messages to the user, where parts of the message consists of dynamically substituted business values e.g. “Your current balance is x, which is too low to purchase the item request” – where x is the customer’s account balance?

  3. Andries Inzé says

    Johan,

    You have a good point there. It would be possible to expand the BusinessException with some list of arguments to be inserted into the translated key.
    Most messageSource implementations can substitute stuff like {0} with an argument list.

  4. Thales Melo says

    Its a good solution, but can i show some snnipet or code example?

  5. Stefaan Huysentruyt says

    I don’t agree completely.

    Sometimes the exception message is more than just an argument substitute construct. The message is possibly calculated from the number and type of the arguments, and a the responsibility of the presentation logic only.

    Therefor I rather create a GenericBusinessException, or even better: GenericDomainException and – if appropriate – start subclassing from these. Why ? Because otherwise (using a key + arguments) presentation logic starts creeping into the service or domain level. Let me explain.

    The sub-classed GenericDomainException is a full fledged domain object, with its own interface which exposes the context of the exception.
    This domain exception is used in a presentation in the presentation layer, which retrieves the context from the exception and links it with some presentation logic.

    Maybe I should clarify with some code. But it ‘s sunday, and I’m well off bounds already here. ;-)

  6. Andries Inzé says

    You do make a valid point that the key+argument will be part of your service layer.

    The whole point of this setup is to NOT make the view layer aware for each and every new exception that might pop up.

    However your point does have merit. I’m thinking in the lines of creating a utility/aspect that will translate all the different exceptions into an generic business exception that can be shown in the view layer. That way the service layer can throw individual different exceptions, the utility class knows how to show these on the screen and can use the context to build the appropriate exception. The controller then recieves a generic exception, with all the information. He does not need to know what particular subclass was thrown.

  7. Jurgen Lust says

    Hi Andries,

    Thanks for this simple but powerful pattern. I’ve integrated it in our in-house development framework, with some WebFlow support in the form of an ExceptionHandler. When a Business Exception is thrown, the ExceptionHandler catches it and puts an error message in the SWF MessageContext, which is then displayed on screen using the JSF
    tag. Other exceptions are not caught and result in a default error page, which is fine, since these are usually the result of a programming error. Perhaps an extra SystemException class could be added for exceptions that are not BusinessExceptions but also not the result of a programming error, for example when the network is down, or the database is unavailable. These should also result in a nice error message for the user, with the possibility to try again later.



Some HTML is OK

or, reply to this post via trackback.

 



Improve Your Life, Go The myEASY Way™