8/6/2019 Erro Handling
1/23
Copyright 2000-2005 Steven Feuerstein - Page 1
Programming Humility:
Dealing with the Reality of Errors
Steven [email protected]
www.quest.com
www.oracleplsqlprogramming
www.qnxo.com
for ODTUG 2005
8/6/2019 Erro Handling
2/23
Copyright 2000-2005 Steven Feuerstein - Page 2
Follow-up from this presentation
Visit the following Oracle PL/SQL portal and
click on Resources:
Download training materials and also a zip
file of all the scripts I will run today.
www.oracleplsqlprogramming.com
8/6/2019 Erro Handling
3/23
Copyright 2000-2005 Steven Feuerstein - Page 3
Robust PL/SQL applications require....
A thorough understanding of the intricacies,
strengths and weaknesses of PL/SQL error
handling;
A clearly-defined strategy for raising,handling and communicating errors within
your application;
Error management code that can be sharedby all developers on the team.
Warning:we can't do this in one hour!
8/6/2019 Erro Handling
4/23
Copyright 2000-2005 Steven Feuerstein - Page 4
So we will...
1. Cover a variety of topics regarding error
handling that are less than
straightforward.
2. Review strengths and weaknesses of the
PL/SQL error handling mechanism.
3. Take a look at the approach I have taken
in Qnxo to build an error managementframework.
8/6/2019 Erro Handling
5/23
Copyright 2000-2005 Steven Feuerstein - Page 5
Different types of exceptions
Deliberate
The code architecture itself deliberately relies on an
exception. Example: UTL_FILE.GET_LINE
Unfortunate It is an error, but one that is to be expected and may not
even indicate a problem. Example: SELECT INTO ->
NO_DATA_FOUND
Unexpected
A "hard" error that indicates a problem within the
application. Example: Primary key lookup raises
TOO_MANY ROWS
exec_ddl_from_file.sql
get_nextline.sf
fullname.pkb
fullname.pkb
8/6/2019 Erro Handling
6/23
Copyright 2000-2005 Steven Feuerstein - Page 6
What the Exception Section Covers
Declarations
Executable Statements
Exception Handlers
BEGIN
EXCEPTION
END
DECLARE
The exception section only handles exceptionsraised in the executable section of a block Note: for a package, this means that the exception section only
handles errors raised in the initialization sectionvalerr.pkg
8/6/2019 Erro Handling
7/23
Copyright 2000-2005 Steven Feuerstein - Page 7
Exceptions and DML
DML statements generally are not rolled backwhen an exception is raised.
This gives you more control over your transaction.
Rollbacks occur with... Unhandled exception from the outermost PL/SQL block;
Exit from autonomous transaction withoutcommit/rollback;
Other serious errors, such as "Rollback segment toosmall".
Corollary: error logs should rely on autonomoustransactions to avoid sharing the same
transaction as the a lication.
log8i.pkg
8/6/2019 Erro Handling
8/23
Copyright 2000-2005 Steven Feuerstein - Page 8
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
Before Oracle Database 10g, the only way is to let
the error go unhandled in your PL/SQL code!
DBMS_UTILITY.FORMAT_ERROR_STACK only
gives you the full error message. And is recommended by Oracle in place of SQLERRM.
Long-standing challenge in PL/SQL:
How can I find the line numberon which an
errorwas raised in PL/SQL?
But in Oracle Database 10g,we have "back trace"!
backtrace.sql
bt.pkg
8/6/2019 Erro Handling
9/23
Copyright 2000-2005 Steven Feuerstein - Page 9
Strengths and weaknesses
Oracle PL/SQL
Error Management:Strengths and Weaknesses
8/6/2019 Erro Handling
10/23
Copyright 2000-2005 Steven Feuerstein - Page 10
PL/SQL error management strengths
Like other modern languages, you define allerror-handling logic in a separate area inyour code.
A single handler will catch and respond to anexception, regardless of where or how it was raised.
You can raise and handle not only systemexceptions, but also your own exceptions.
Either with RAISE_APPLICATION_ERROR (when youneed to communicate the error to your user) or withuser-defined EXCEPTIONs.
8/6/2019 Erro Handling
11/23
Copyright 2000-2005 Steven Feuerstein - Page 11
PL/SQL error management weaknesses
The EXCEPTION is a limited type of data.
Only has two attributes: code and message. Unlike with
Java, it cannot be extended to include more information.
You can RAISE and handle an exception, but it cannot bepassed as an argument in a program.
No way to specify the possible exceptions that
can be raised by a program.
You have to examine the implementation to deduce such
information.
That somewhat silly -20,999 - -20,000 range.
8/6/2019 Erro Handling
12/23
Copyright 2000-2005 Steven Feuerstein - Page 12
Shoring up the Weaknesses
Let's take a look at theerror handlingarchitecture of Qnxo
for an example.
8/6/2019 Erro Handling
13/23
Copyright 2000-2005 Steven Feuerstein - Page 13
The Qnxo approach to error handling
Object-like representation of an error
Oracle's EXCEPTION is very limited, so why not createour own "error instance"?
Bypass restrictions on the error number rangeentirely.
Let's use error names in our code instead!
Or use positive error numbers...
Rely on a single package to raise and handleerrors.
Make it harder for programmers to not follow thestandards.
8/6/2019 Erro Handling
14/23
Copyright 2000-2005 Steven Feuerstein - Page 14
Object-like representation of an exception
An error is a row in the error table, with many
more attributes than simply code and
message, including:
Dynamic message (substitution variables)
Help message (how to recover from the problem)
An error instance is one particular
occurrence of an error. Associated with it are one or more values that reflect
the context in which the error was raised.
qd_error.erd
8/6/2019 Erro Handling
15/23
Copyright 2000-2005 Steven Feuerstein - Page 15
ERD for error definition tables
8/6/2019 Erro Handling
16/23
Copyright 2000-2005 Steven Feuerstein - Page 16
Specifying the error
How should I raise (and handle)my application errors?
Just use -20000 all the time?Pick one of those 1000 numbers?
What about all those positive numbers?What about errornames?
8/6/2019 Erro Handling
17/23
Copyright 2000-2005 Steven Feuerstein - Page 17
Raise/handle errors by name or number
The above trigger fragment illustrates a commonproblem: Hard-coding of error numbers andmessages.
Certainly, it is better to use named constants, as in:
BEGIN
IF employee_rp.is_to_young (:new.hire_date)
THENRAISE_APPLICATION_ERROR (
-20175, 'You must be at least 18 years old!');
END IF;
BEGINIF employee_rp.is_to_young (:new.hire_date)
THEN
RAISE_APPLICATION_ERROR (employee_rp.en_too_young
, employee_rp.em_too_young);
END IF;
But...
8/6/2019 Erro Handling
18/23
Copyright 2000-2005 Steven Feuerstein - Page 18
Stop-and-go programming
The reality is we can't know in advanceall of the different errors we'll have tohandle. With this approach, for each new
error, I must: Stop writing my current program.
Update my error package (or repository that thengenerates the error package).
Recompile the package and recompile allprograms marked invalid.
Finally return to my program. Where was I?
8/6/2019 Erro Handling
19/23
Copyright 2000-2005 Steven Feuerstein - Page 19
How about "top-down" error definition?
Use an error name (literal value).
The code compiles now.
Later, I define that error in the repository.
No central point of failure.
Downsides: risk of typos, runtime notification of"undefined error."
BEGIN
IF employee_rp.is_to_young (:new.hire_date)
THEN
qd_runtime.raise_error ('EMPLOYEE-TOO-YOUNG'
, name1_in =>'LAST_NAME'
, value1_in =>:new.last_name);
END IF;
8/6/2019 Erro Handling
20/23
Copyright 2000-2005 Steven Feuerstein - Page 20
Package to raise, handle and report errors
Rather than have each programmer write
their own error handling code, provide a
single package to standardize the way errors
are raised, handled and reported.
WHEN e_integ_constraint_failure THEN
DECLARE
l_owner ALL_CONSTRAINTS.OWNER%TYPE;
l_name ALL_CONSTRAINTS.CONSTRAINT_NAME%TYPE;BEGIN
get_constraint_info (l_owner, l_name);qd_runtime.raise_error (
error_name_in =>'INTEGRITY-CONSTRAINT-FAILURE'
,name1_in =>'OWNER', value1_in => l_owner
,name2_in =>'CONSTRAINT_NAME', value2_in => l_name
,name3_in =>'TABLE_NAME', value3_in =>'SA_APPLICATION');
END;
8/6/2019 Erro Handling
21/23
Copyright 2000-2005 Steven Feuerstein - Page 21
Runtime error gathering/construction
When an error occurs, you want to gather up
as much information as possible and make it
available for support and users.
The default is a number and string. That is just a little
bit limiting.
Other useful information...
Error stack, backtrace stack (Oracle10g only), callstack, environment info (machine name, OS, etc.) and of
course all that context-specific, application-specific
information.qd_runtime.pkb
8/6/2019 Erro Handling
22/23
8/6/2019 Erro Handling
23/23
Copyright 2000-2005 Steven Feuerstein - Page 23
Conclusions for PL/SQL error management
Make sure you understand how it all works
Exception handling is tricky stuff.
Set standards before you start coding
It's not the kind of thing you can easily add in later.
Use shared infrastructure components
Everyone and all programs need to handle errors the same way.
Don't accept the limitations of Oracle's current
implementation.
There is often a lot you can do to improve the situation.
Top Related