Exception Serializer in Lagom

In this blog, I will show you how to handle error responses from a Lagom service and convert them into well-defined exceptions using exception serializers.

Suppose we have an unmanaged service in Lagom. The unmanaged service hits a target service and the success response is deserialized into a POJO corresponding to the service call. But in the case of an error response, we get deserialization exception since the response with details of the error cannot be mapped to that POJO.

Using Lagom’s ExceptionSerializer, we can map all the responses with status codes in the range of 400-500 to appropriate exceptions specific to the service with a well-defined message. It allows the client of the service to take a suitable action based on the exception generated.

Exception serializers convert exceptions to RawExceptionMessage. The raw exception message contains a status code, a message body, and a protocol descriptor which defines the content type of the message. It also allows an exception to be recreated from an error code and their serialized form.

This is how the exception serializer is defined:

public interface ExternalService extends Service {
    default Descriptor descriptor() {
        return Service.named("external-service")
                        Service.restCall(Method.GET, "/user", this::getUser)

     ServiceCall getUser();


The ExceptionSerializer subclass needs to override the serialize and deserialize methods which define how the exceptions are serialized to RawExceptionMessage and deserialized to Throwable. Following example shows how it can be done.

public class ExternalServiceExceptionSerializer implements ExceptionSerializer {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    public static final ExternalServiceExceptionSerializer INSTANCE = new ExternalServiceExceptionSerializer();

    public RawExceptionMessage serialize(Throwable exception, Collection accept) {
        return null;

    public Throwable deserialize(RawExceptionMessage message) {
        return ExceptionFactory.getInstance(mapExceptionToFault(message));

    Fault mapExceptionToFault(RawExceptionMessage message) {
        Fault fault;

        try {
            String errorJson = message.messageAsText();
            fault = OBJECT_MAPPER.readValue(errorJson, Fault.class);
        } catch (IOException ex) {

            fault = Fault.builder()
                    .errorMessage("No payload available")
        return fault;


The above class takes the serialized exception message(RawExceptionMessage) and maps it to a Fault POJO containing the error string.

public class Fault {
    String errorMessage;


The Fault POJO is provided to an exception factory class which determines the exception to throw based on the contents of the error message.

public class ExceptionFactory {

    public static Throwable getInstance(Fault fault) {
        if (fault == null)
            return null;
        return determineException(fault);

    private static Throwable determineException(Fault fault) {
        String message = fault.getErrorMessage();

        if (StringUtils.isNotEmpty(message) && message.contains("Requires authentication")) {
            return new AuthenticationException(fault);
        return new GenericException(fault);

    public static class AuthenticationException extends RuntimeException {

        Fault fault;

        public AuthenticationException(Fault fault) {
            this.fault = fault;

    public static class GenericException extends RuntimeException {

        Fault fault;

        public GenericException(Fault fault) {
            this.fault = fault;

That is it. We have now successfully implemented exception serializer in our service. Now the service will always throw the custom exceptions specified in the exception factory whenever the backend service gives the error response.

Hope you enjoyed reading. The complete code is available here.

References :




This entry was posted in Java and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s