5. Exception Handling

 Documentation Summary
 Page Summary

Exception Handling

The server exceptions can be handled on the client-side by defining a fault callback on each remote call. It works fine but it is very tedious and you can always forget a case, in which case the error will be either ignored or result in a Flex error popup that is not very elegant.

To help dealing with server exceptions, it is possible to define common handlers for particular fault codes on the client-side, and exception converters on the server-side, to convert server exceptions to common fault codes.

On the server, you have to define an ExceptionConverter class. For example we could write a converter to handle the JPA EntityNotFoundException (in fact there is also a built-in converter for all JPA exceptions):

EntityNotFoundExceptionConverter.java
public class EntityNotFoundExceptionConverter implements ExceptionConverter {

    public static final String ENTITY_NOT_FOUND = "Persistence.EntityNotFound";
    
    public boolean accepts(Throwable t, Throwable finalException) {
        return t.getClass().equals(javax.persistence.EntityNotFoundException.class);
    }

    public ServiceException convert(
        Throwable t, String detail, Map<String, Object> extendedData) {

        ServiceException se = new ServiceException(
            ENTITY_NOT_FOUND, t.getMessage(), detail, t
        );
        se.getExtendedData().putAll(extendedData);
        return se;
    }
}

This class will intercept all EntityNotFound exceptions on the server-side, and convert it to a proper ENTITY_NOT_FOUND fault event.

The argument finalException contains the deepest throwable in the error and can be used to check if some higher level exception converter should be used to handle the exception. For example, the HibernateExceptionConverter checks if the exception is wrapped in a PersistenceException, in which case it lets the JPA PersistenceExceptionConverter accept the exception.

This exception converter has to be declared on the GDS server config :

  • When using scan="true" in granite-config.xml, ensure that there is a META-INF/granite-config.properties file (even empty) in the jar containing the exception converter class (same principle than the seam.properties file to specify which jars need to be scanned).
  • When not using automatic scan, you can add this in granite-config.xml :
    <exception-converters>
      <exception-converter type="com.package.SomeExceptionConverter"/>
    </exception-converters>
    

On the Flex side, you then have to define an exception handler class:

EntityNotFoundExceptionHandler.as
public class EntityNotFoundExceptionHandler implements IExceptionHandler {

    public function accepts(emsg:ErrorMessage):Boolean {
        return emsg.faultCode == "Persistence.EntityNotFound";
    }

    public function handle(context:BaseContext, emsg:ErrorMessage):void {
        Alert.show("Entity not found: " + emsg.message);
    }
}

... and register it as an exception handler for the Tide context in a static initializer block to be sure it is registered before anything else happens.

MyApp.mxml
<mx:Application>
    <mx:Script>
        Seam.getInstance().addExceptionHandler(EntityNotFoundExceptionHandler);
    </mx:Script>
</mx:Application>

 


Browse Space

- Pages
- Blog
- Labels
- Attachments
- Bookmarks
- Mail
- Advanced

Explore Confluence

- Popular Labels
- Notation Guide

Your Account

Log In

Other Features

Add Content


Copyright © 2011 Granite Data Services S.A.S. All Rights Reserved.