Developer Guide
Also available as:
loading table of contents...

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., InputStreamCallback, OutputStreamCallback, or StreamCallback). That is, during the processing of a FlowFile's content. Callbacks are allowed to throw either RuntimeException or 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 Exception or 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.