There are three types of error that can arise when an activity is processing. Each of these has an exception associated with it that the activity can throw. In addition the pipes used by activities for their inputs and outputs can also throw exceptions. In this section we describe what exceptions should be used when and how to handle them.
Errors of this type includes:
In such conditions activities should raise an exception that is wrapped within an exception of type:
uk.org.ogsadai.activity.ActivityUserException
There are error that may not be the client's fault. For example, there is a problem using a server-side resource, the activity is not configured correctly, some server-side component experiences problems. In such conditions activities should raise an exception that is wrapped within an exception of type:
uk.org.ogsadai.activity.ActivityProcessingException
An activity which is providing input to this activity is
terminated. This will be indicated by the throwing of a
PipeTerminatedException when an
attempt is made to use the block reader corresponding to the input
pipe (we discuss this further below).
In such conditions activities should raise an exception that is wrapped within an exception of type:
uk.org.ogsadai.activity.ActivityTerminatedException
It is important that
PipeTerminatedException caught and is
mapped to a
ActivityTerminatedException so that
the activity status can record that it terminated as a consequence of
another activity rather than something occuring within it itself.
The pipe interfaces:
uk.org.ogsadai.activity.io.BlockReader uk.org.ogsadai.activity.io.BlockWriter
can throw exceptions when an activity reads and writes data. These exceptions are as follows:
uk.org.ogsadai.activity.io.PipeClosedException
This exception is thrown if the activity at the other end of the pipe has indicated that it wants no more data. In this situations most activities simply stop producing their data.
uk.org.ogsadai.activity.io.PipeIOException
This exception is thrown if a problem occurs when using the pipe that is not due to it being closed or terminated.
uk.org.ogsadai.activity.io.PipeTerminatedException
This exception is thrown if the request to which the pipe belongs is terminated prematurely due to an error elsewhere.
BlockReader can throw:
PipeIOExceptionPipeTerminatedException
BlockWriter can throw:
PipeClosedExceptionPipeIOExceptionPipeTerminatedException
You will never have to throw a pipe exception but your activities will
have to handle them if it has inputs or outputs. How these exceptions
are handled by an activity affects how the activity behaves. In,
particular, activities are typically notified that the are to
terminate by receiving a
PipeTerminatedException. We therefore
recommend the following when handling pipe exceptions:
PipeClosedException - iterative
activities that sub-class
uk.org.ogsadai.activity.MatchedIterativeActivity
may want to invoke
iterativeStageComplete(). Other
activities may just swallow the exception.
PipeIOException - should
be caught and wrapped and rethrown as an
uk.org.ogsadai.activity.io.ActivityPipeProcessingException.
This is a sub-class of
ActivityProcessingException
,
PipeTerminatedException -
should be caught and an
ActivityTerminatedExxception
thrown.
In section Chapter 107, How to declare activity inputs for matched activities we describe the
various ways to declare activity inputs for matched activities and
also how inputs are provided to these activities. For character or
binary data you will be given a reference to a
java.io.Reader or a
java.io.InputStream.
If this is the canse then, if an error occurs it is important not to close these objects. These objects wrap the associated input pipes and so closing them can lead to problems.
If an error has occured just throw an appropriate exception. The activity framework will close all the inputs and outputs in such a way that the error is correctly propagated through the workflow.
Here is an example of how errors are handled in:
uk.org.ogsadai.activity.files.ReadFromFileActivity
try
{
...
}
catch (FileResourceUseException e)
{
// The client doesn't have permission to access the file.
// Client's fault for trying to access it.
throw new ActivityUserException(e);
}
catch (FileNotFoundException e)
{
// The file is not found or is a directory.
// Client's fault for specifying this.
throw new ActivityUserException(e);
}
catch (PipeClosedException e)
{
// No more output wanted, so ignore.
iterativeStageComplete();
}
catch (PipeIOException e)
{
// Something internal went wrong with input or output pipe.
throw new ActivityPipeProcessingException(e);
}
catch (PipeTerminatedException e)
{
// The input or output pipe was terminated.
throw new ActivityTerminatedException();
}
catch (IOException e)
{
// Something went wrong when using the file that was
// not the client's fault e.g. a problem with the file system.
throw new ActivityProcessingException(ErrorID.GENERAL_IO_ERROR, e);
}