Improve error handling – Exceptions

The Error Handling in Grails has changed with the latest support from Groovy. In this case we will make use of the “Declarative Controller Exception Handling” feature of Grails.

“Grails controllers support a simple mechanism for declarative exception handling. If a controller declares a method that accepts a single argument and the argument type is java.lang.Exception or some subclass of java.lang.Exception, that method will be invoked any time an action in that controller throws an exception of that type. See the following example”:

class ElloController  {
    def index() { 
        def message="Resource was not found"
        throw new NotFoundException(message);
    }
 
    def handleNotFoundExceptio(NotFoundException e) {
        response.status=404
        render ("error found")
}

In the previous example, a simple blank page will the message Error not found will be shown on the invocation of the controller
Important:

  • The exception handler method names can be any valid method name. The name is not what makes the method an exception handler, the Exception argument type is the important part.
  • The exception handler methods can do anything that a controller action can do including invoking render, redirect, returning a model, etc.

We need to avoid including redundant methods in every class. Therefore traits in Grails provide a clever way to include some methods to a class. With regard to Exceptions, we create a traits groovy file including the neccessary Exception Handlers. Example:

package com.apo4.exception
 
trait NotFoundExceptionHandler {
    def handleNotFoundExceptio(NotFoundException e) {
        response.status=404
        render ("error found")
    }
}

This trait can be included in any controller through an implements directive. Thus our old controller becomes:

import com.apo4.exception.NotFoundExceptionHandler
import com.apo4.exception.NotFoundException
 
class ElloController implements NotFoundExceptionHandler {
    def index() { 
        throw new NotFoundException("Resource was not found");
    }
}

As it can be seen, the methods are no longer in the controller but are moved into the traits and included from the implements directive.

Exceptions can easily be invoked in services as well. *Controllers consuming such services should have the implementation of the traits or a method to Handle the Exceptions.

import com.apo4.exception.NotFoundException
class ElloService {
    def serviceMethod() {
        throw new NotFoundException("Resource was not found - thrown from service");
    }
}

References

Dillinger uses a number of open source projects to work properly: