A protected block may handle multiple steps. 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.