Exception object
An Exception object you can pass around between procedures. It was a bit of an experiment and I haven't found a real use for it yet, but maybe that's just because I've been working on warehouse systems for a while. Let me know if you find a use for it!
-- EXCEPTION object type
-- William Robertson 2003, www.williamrobertson.net
create or replace type exception_ot as object
( message varchar2(32767)
, error_code integer
, module varchar2(30)
, action varchar2(100)
, os_logdir varchar2(80)
, os_logfile varchar2(70)
, raised timestamp
, member procedure include_text
( p_word1 varchar2 default null
, p_word2 varchar2 default null
, p_word3 varchar2 default null )
, member procedure log
( p_log_to_database_yn varchar2 default 'Y'
, p_log_to_file_yn varchar2 default 'N'
, p_send_mail_yn varchar2 default 'N' )
, member procedure raise
( p_log_to_database_yn varchar2 default 'N'
, p_log_to_file_yn varchar2 default 'N'
, p_send_mail_yn varchar2 default 'N' )
, constructor function exception_ot
( p_message varchar2
, p_error_code integer default -20000
, p_module varchar2 default null
, p_action varchar2 default null
, p_logdir varchar2 default null
, p_logfile varchar2 default null )
return self as result
, member procedure print )
/
show errors
create or replace type body exception_ot
as
member procedure include_text
( p_word1 varchar2 default null
, p_word2 varchar2 default null
, p_word3 varchar2 default null )
is
begin
message := replace(replace(replace(message,'[1]',p_word1),'[2]',p_word2),'[3]',p_word3);
end;
member procedure log
( p_log_to_database_yn varchar2 default 'Y'
, p_log_to_file_yn varchar2 default 'N'
, p_send_mail_yn varchar2 default 'N' )
is
begin
if upper(substr(p_log_to_database_yn,1,1)) = 'Y' then
logger.write(message, module, action);
end if;
if upper(substr(p_log_to_file_yn,1,1)) = 'Y' then
logger.write(message, module, action);
end if;
if upper(substr(p_send_mail_yn,1,1)) = 'Y' then
logger.write(message, module, action);
end if;
end;
member procedure raise
( p_log_to_database_yn varchar2 default 'N'
, p_log_to_file_yn varchar2 default 'N'
, p_send_mail_yn varchar2 default 'N' )
is
begin
raise_application_error
( nvl(error_code,-20000)
, message
, true );
end;
constructor function exception_ot
( p_message varchar2
, p_error_code integer default -20000
, p_module varchar2 default null
, p_action varchar2 default null
, p_logdir varchar2 default null
, p_logfile varchar2 default null )
return self as result
is
v_module varchar2(30);
v_action varchar2(100);
v_dummy pls_integer;
begin
message := p_message;
error_code := nvl(p_error_code,-20000);
if p_logdir is not null then
begin
select directory_name into os_logdir
from all_directories
where p_logdir in (directory_name, directory_path)
order by
decode(p_logdir, directory_name, 1,2);
begin
select 1 into v_dummy
from user_tab_privs_recd
where table_name = self.os_logdir
and privilege = 'WRITE';
exception
when no_data_found then
raise_application_error
( -20999
, 'user ' || user || ' lacks write permission to directory "' || p_logdir || '".' );
end;
exception
when no_data_found then
raise_application_error
( -20999
, 'No such directory "' || p_logdir ||
'" defined in database.' );
end;
end if;
os_logfile := p_logfile;
raised := systimestamp;
if p_module is null
or p_action is null
then
dbms_application_info.read_module(v_module, v_action);
module := nvl(p_module,v_module);
action := coalesce(p_action,v_action,'Unknown');
end if;
return;
end;
member procedure print
is
begin
echo(error_code || ': ' || message);
end;
end;
/
show errors
create or replace package error
as
e_general constant exception_ot := exception_ot('An error occurred', -20001);
e_no_such constant exception_ot := exception_ot('No such [1]', -20002);
e_job constant exception_ot := exception_ot('Job submit error', -20003);
end error;
/
prompt demo exception_ot:
create or replace procedure test_exception
( p_test varchar2 )
as
e_no_such_thing exception_ot := error.e_no_such;
v_dummy varchar2(1);
begin
select dummy into v_dummy from dual where dummy = p_test;
exception
when no_data_found then
-- e_no_such_thing.message := sqlerrm;
e_no_such_thing.include_text('dummy "' || p_test || '"');
e_no_such_thing.print();
e_no_such_thing.raise();
end;
/
PROMPT Success:
exec test_exception('X')
PROMPT Failure:
exec test_exception('Y')