Exceptions within a callback: IOException, RuntimeException
More often than not, when an Exception occurs in a Processor, it occurs from within a callback (I.e.,
StreamCallback). That is, during the processing of a FlowFile's content. Callbacks are allowed to throw either
IOException. In the case of RuntimeException, this Exception will propagate back to the
onTrigger method. In the case of an
IOException, the Exception will be wrapped within a ProcessException and this ProcessException will then be thrown from the Framework.
For this reason, it is recommended that Processors that use callbacks do so within a
try/catch block and catch
ProcessException as well as any other
RuntimeException that they expect their callback to throw. It is not recommended that Processors catch the general
Throwable cases, however. This is discouraged for two reasons.
First, if an unexpected RuntimeException is thrown, it is likely a bug and allowing the framework to rollback the session will ensure no data loss and ensures that DataFlow Managers are able to deal with the data as they see fit by keeping the data queued up in place.
Second, when an IOException is thrown from a callback, there really are two types of IOExceptions: those thrown from Processor code (for example, the data is not in the expected format or a network connection fails), and those that are thrown from the Content Repository (where the FlowFile content is stored). If the latter is the case, the framework will catch this IOException and wrap it into a
FlowFileAccessException, which extends
RuntimeException. This is done explicitly so that the Exception will escape the
onTrigger method and the framework can handle this condition appropriately. Catching the general Exception prevents this from happening.