How Oracle PL/SQL Exceptions Propagate?
A PL/SQL program is an anonymous block, a procedure, or a function. This program can call other procedures or functions, or nest an anonymous block within that block. So at any given point in execution, there might be several layers of PL/SQL blocks nested within other blocks. Each PL/SQL block can have its own exception section, or it can be totally void of exception handlers.
To determine the appropriate exception-handling behavior, PL/SQL follows rules regarding:
- Scope: The PL/SQL block or blocks in which an exception can be raised and handled.
- Propagation: The way in which an exception is passed back through enclosing blocks until it is handled or is resolved to be an unhandled exception.
When an exception is raised, if PL/SQL cannot find a handler for it in the current block or subprogram, the exception propagates. That is, the exception reproduces itself in successive enclosing blocks until a handler is found or there are no more blocks to search. If no handler is found, PL/SQL returns an unhandled exception error to the host environment.
Exceptions cannot propagate across remote procedure calls done through database links. A PL/SQL block cannot catch an exception raised by a remote subprogram.
The following three Figures illustrate the basic exception propagation rules defined in the Oracle PL/SQL.
Figure 1 Propagation Rules: Example 1
In the above figure 1, the innermost block has an exception handling section, when exception A is raised, PL/SQL first checks to see if the exception A can be handled in this section. PL/SQL scans the exception handlers and finds that it is handled in this block locally, after which the execution resumes in the enclosing block.
Figure 2 Propagation Rules: Example 2
In the above figure 2, when exception B is raised, PL/SQL first checks to see if the exception B can be handled in the innermost section. Because it was not handled, PL/SQL closes that block and raises the exception B in the enclosing block. Control immediately passes to the outer exception handling section. PL/SQL scans the exception handlers and finds that it is handled in this block, so the code for that handler is executed, after which control passes passes to the host environment.
Figure 3 Propagation Rules: Example 3
In the above figure 3, when exception C is raised, PL/SQL scans all the exception handlers and finds that it can't be handled, so an unhandled exception is returned to the host environment.
An exception can propagate beyond its scope, that is, beyond the block in which it was declared. Consider the following example:
BEGIN
DECLARE ---------- sub-block begins
past_due EXCEPTION;
due_date DATE := trunc(SYSDATE) - 1;
todays_date DATE := trunc(SYSDATE);
BEGIN
IF due_date < todays_date THEN
RAISE past_due;
END IF;
END; ------------- sub-block ends
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
/
Because the block that declares the exception past_due
has no handler for it, the exception propagates to the enclosing block. But the enclosing block cannot reference the name PAST_DUE
, because the scope where it was declared no longer exists. Once the exception name is lost, only an OTHERS
handler can catch the exception. If there is no handler for a user-defined exception, the calling application gets this error:
ORA-06510: PL/SQL: unhandled user-defined exception