When a step of a job fails, the job is aborted. To perform some clean-up actions before the job finally exits (such as logging or sending email notifications), you can create steps of type "error/success handling step". The error/success handling steps allow you to protect the execution of one or more steps, referred to as a "protected block". The following diagram illustrates the structure of a protected block.
Structure of a protected block
When any of the steps within the protected block fail, error handlers control what happens before the job finally exits. Error handlers can be one of the following:
•On Success (instructs the system to perform some action if all steps in the protected block were successful)
•On Error (instructs the system to perform some action if any of the steps in the protected block were not successful)
•Always (instructs the system to perform some action regardless of whether the steps in the protected block were successful)
When the protected block finishes executing, FlowForce Server executes any defined handlers based on the outcome. For example, on the diagram shown above, the protected steps are Step A and Step B, and the error handling logic is as follows:
•If A fails, then A, C and E will be executed.
•If B fails, then A, B, C and E will be executed.
•If A and B are successful, then A, B, D and E will be executed.
In practice, it is not necessary (although it is possible) to define all three handler types for every job that you want to handle. The most common scenario is to define only On Error and Always handlers. For example, the image below illustrates a simple protected block with On Error and Always.
The first step runs a script from the C:\scripts directory by invoking the \system\shell\commandline function. The execution of this step is protected by two handlers: On Error and Always. The On Error handler will be triggered only if the execution of the first step fails. More specifically, if the first step fails, the error handling step sends an email that contains the ID of the failed job instance in the subject line. The Always handler is executed unconditionally, regardless of whether the first step was successful or not. This handler logs a message by running a script from the C:\scripts directory. For a more detailed worked example similar to the one illustrated above, see Adding Error Handling to a Job.
Considerations when implementing exception handling
In the configuration illustrated previously, a single step was being handled, namely, the first step of the job. To handle multiple steps, simply add them one after the other inside a protected block. In terms of their structure, steps within a protected block are exactly like the standard, non-handled steps (for example, you can execute functions, embed FlowForce expressions, create loops, and so on). In some cases, however, steps inside protected blocks may require special treatment, as discussed below.
The first thing to consider is that an exception handler can contain multiple execution steps. For example, one step generates a file, another one applies a transformation to it, and the third one sends it as an email. This is a valid configuration. Still, handlers with multiple execution steps add complexity and should be weighed out carefully, because an error may occur inside the error handler step itself, for example.
When multiple steps exists inside the same handler, they will run sequentially until all of them are executed, or until a step fails. Any steps after the failing step will not be executed. Nevertheless, if a handler fails, its outcome will be handled by an outer handler, if one exists.
To address this, you might want to limit the number of steps inside the handler, and thus the chance of error. The fewer the steps inside a handler, the higher the chances that the handler will run to completion. If any step is critical in the sense that subsequent ones depend on it, you could add, for example, a new error handler for this step specifically, and continue execution of dependent steps only on success.
Another thing to have in mind is that one cannot refer to the result of a step that's within a protected block, from the exception handler. The reason is that, if a step fails, the result of the protected block would be something undefined, and it is impossible to process an undefined result.
Therefore, if an execution step is placed within a protected block with an exception handler, it is not possible to access the result of that execution step within the exception handler. It doesn't matter if the exception handler is On Success, On Error or Always.
The restriction applies only for steps within the protected block. Results of steps that are outside the protected block can still be accessed within the exception handler. To understand this better, let's consider the following example job:
In the job illustrated above, each step has a result. For example, the first step has result1, the second step has result2, and so on. If you need to access the value of any of these results, note the following:
•Step 1 is outside of a protected block, so its result is accessible to all other subsequent steps. Namely, result1 is accessible from step 2 or step 3, and also from the error handler.
•Steps 2 and 3 are inside a protected block, which makes their result accessible only from subsequent steps of the same protected block, but not from any handler. In other words, result2 is accessible from step 3 but it is not accessible from the error handler. The result3 is not accessible at all, because there are no other steps following it.
•Finally, the result of the error handler, result_handler, is not accessible to any other steps, because it is inside a handler and is the only and last step of the handler. Had there been more steps after it, then they could have consumed the result_handler result.
Having in mind the above, the design of the protected block should account for the visibility of results. The exact solution depends on the case. For example, if the result of a step inside an On Error block is important because it creates a file name, you can enclose it inside its own protected block (nested protected block) and call the failed-step function to get the erroneous output and still create the file. Although it does not identify the step that caused the error, this function returns a result type which includes error information if one occurred. A result represents the abstract result of running a shell command, a MapForce transformation, or a StyleVision stylesheet and can be handled not only when it produces the expected output, but also when an error occurs. This is best understood by example and is further discussed in Adding Error Handling to a Job.