Chapter 120. How to write OGSA-DAI compliant exceptions

120.1. Why write OGSA-DAI compliant exceptions?
120.2. How to write a new exception
120.3. How to associate an exception with an error ID
120.4. How to write a constructor for your exception
120.5. How to chain exceptions

120.1. Why write OGSA-DAI compliant exceptions?

By extending OGSA-DAI's base exception classes you can write exceptions that exploit OGSA-DAI's internationalization functionality.

This page assumes that you are familiar with OGSA-DAI's support for internationalization, message bundles, message IDs and error IDs as described earlier in on Chapter 117, How to register message bundles and on Chapter 118, How to log internationalized messages.

120.2. How to write a new exception

First you should decide whether you wish your exception to be checked or unchecked and declare your exception to extend the appropriate OGSA-DAI class:

  • For checked exceptions - those that must be declared in the throws clause of methods - your exception should extend:
    uk.org.ogsadai.exception.DAIException
    
  • For unchecked exceptions - your exception should extend:
    uk.org.ogsadai.exception.DAIUncheckedException
    

For example:

package com.example;

import uk.org.ogsadai.exception.DAIException;

public class MyNewException extends DAIException 
{
    // Exception in progress - see below for more of the body.
}

120.3. How to associate an exception with an error ID

You should now define an error ID for your exception. We described this already in Section 118.3, “How to define error IDs”

So, our example exception would now look like the following:

package com.example;

import uk.org.ogsadai.exception.DAIException;
import uk.org.ogsadai.exception.ErrorID;

public class MyNewException extends DAIException 
{
    // Declaration of error ID constant whose value is a
    // unique namespace-qualified error key.
    private static final ErrorID MY_NEW_ERROR =
        new ErrorID("com.example.MY_NEW_ERROR");

    // Exception in progress - see below for more of the body.
}

Similarly, you should ensure that your message bundle has an entry for the error key associated with your error ID. For example:

com.example.MY_NEW_ERROR=A bad value was encountered. The value was {0} when I was expecting {1}.

120.4. How to write a constructor for your exception

You can now complete your exception by providing a constructor. This should pass the error ID to the super-class constructor and also any parameters required by the associated error key as specified in the message bundle.

Arguments required by the associated error key, as specified in a message bundle, should be provided a java.lang.Object array with the entries in the array in the same order as the placeholders in the message string associated with the error key. For example:

package com.example;

import uk.org.ogsadai.exception.DAIException;
import uk.org.ogsadai.exception.ErrorID;

public class MyNewException extends DAIException 
{
    // Declaration of error ID constant whose value is a
    // unique namespace qualified ID.
    private static final ErrorID MY_NEW_ERROR =
        new ErrorID("com.example.MY_NEW_ERROR");

    public MyNewException(String badValue, String expectedValue)
    {
        // Note how the order of values in the array matches that
        // expected by the message bundle entry for error key
        // com.example.MY_NEW_ERROR shown above.
        super(MY_NEW_ERROR, new Object[] {badValue, expectedValue});
    }
}

120.5. How to chain exceptions

To link exceptions into causal chains you can use the standard java.lang.Throwable initCause(Throwable) method, e.g.

package com.example;

import uk.org.ogsadai.exception.DAIException;
import uk.org.ogsadai.exception.ErrorID;

public class MyOtherNewException extends DAIException 
{
    private static final ErrorID MY_OTHER_NEW_ERROR =
        new ErrorID("com.example.MY_OTHER_NEW_ERROR");

    public MyOtherNewException(String badValue, String expectedValue,
                               Throwable cause)
    {
        super(MY_OTHER_NEW_ERROR, new Object[]{badValue, expectedValue});
        // Set up the causal chain.
        super.initCause(cause);
    }
}