git-svn-id: http://locode01.ad.dom/svn/WEBMIP/trunk@12551 248e525c-4dfb-0310-94bc-949c084e9493
472 lines
19 KiB
Plaintext
472 lines
19 KiB
Plaintext
CREATE OR REPLACE PACKAGE cout_err IS
|
|
|
|
g_header CONSTANT VARCHAR2(160) := '$Header: /Isle Of Grain/Database/PLSQL/cout_err.pck 3 1/04/05 16:13 Hardya $';
|
|
g_revision CONSTANT VARCHAR2(160) := '$Revision: 3 $';
|
|
|
|
/**
|
|
-- Package containing the common error utility modules used by the Access Manager application
|
|
-- #version $Revision: 3 $
|
|
-- #author Andy Hardy
|
|
*/
|
|
|
|
/** Specifies logging to be table-based (ERROR_LOGS), this the default log method.*/
|
|
c_table CONSTANT PLS_INTEGER := 1;
|
|
/** Specifies logging to be file-based. */
|
|
c_file CONSTANT PLS_INTEGER := 2;
|
|
/** Specifies logging to be screen-based. */
|
|
c_screen CONSTANT PLS_INTEGER := 3;
|
|
|
|
/** Specifies the substitution values that could be passed into any generated error message */
|
|
TYPE g_t_substitution_list IS TABLE OF VARCHAR2(80) INDEX BY BINARY_INTEGER;
|
|
c_empty_substitution_list g_t_substitution_list;
|
|
|
|
/**
|
|
-- Reports the error and RAISES an exception to halt program execution
|
|
#param p_exception_number The exception to be raised, defaults to SQLCODE
|
|
#param p_exception_message The message to be logged, defaults to the matching message from EXCEPTION_MESSAGES
|
|
#param p_helper_call If TRUE, indicates that this report is being produced through a helper function
|
|
#param p_error_group The error group that this error should be reported as a part of
|
|
*/
|
|
PROCEDURE report_and_stop(p_exception_number IN INTEGER := SQLCODE
|
|
,p_exception_message IN VARCHAR2 := NULL
|
|
,p_substitution_list IN g_t_substitution_list := c_empty_substitution_list
|
|
,p_helper_call_level IN NUMBER := 0
|
|
,p_error_group IN VARCHAR2 := 'APPLICATION'
|
|
,p_severity IN VARCHAR2 := 'E'
|
|
,p_source IN VARCHAR2 := NULL);
|
|
|
|
/**
|
|
-- Reports the error and continues program execution
|
|
#param p_exception_number The exception to be raised, defaults to SQLCODE
|
|
#param p_exception_message The message to be logged, defaults to the matching message from EXCEPTION_MESSAGES
|
|
#param p_helper_call If TRUE, indicates that this report is being produced through a helper function
|
|
#param p_error_group The error group that this error should be reported as a part of
|
|
*/
|
|
PROCEDURE report_and_go(p_exception_number IN INTEGER := SQLCODE
|
|
,p_exception_message IN VARCHAR2 := NULL
|
|
,p_substitution_list IN g_t_substitution_list := c_empty_substitution_list
|
|
,p_helper_call_level IN NUMBER := 0
|
|
,p_error_group IN VARCHAR2 := 'APPLICATION'
|
|
,p_severity IN VARCHAR2 := 'E'
|
|
,p_source IN VARCHAR2 := NULL);
|
|
|
|
/**
|
|
-- Allows the specification of the log destination
|
|
#param p_target The destination (as defined by the constants c_table, c_file and c_screen
|
|
#param p_dir If file has been chosen, allows the log directory to be specified
|
|
#param p_file If file has been chosen, allows the log filename to be specified
|
|
*/
|
|
PROCEDURE logto(p_target IN PLS_INTEGER
|
|
,p_dir IN VARCHAR2 := NULL
|
|
,p_file IN VARCHAR2 := NULL);
|
|
|
|
/**
|
|
-- Returns the current log destination.
|
|
#return Returns a value matching c_table, c_file or c_screen
|
|
*/
|
|
FUNCTION logging_to RETURN PLS_INTEGER;
|
|
|
|
/**
|
|
Return an identification string to link to the source control system.
|
|
*/
|
|
FUNCTION about RETURN VARCHAR2;
|
|
|
|
END cout_err;
|
|
/
|
|
CREATE OR REPLACE PACKAGE BODY cout_err IS
|
|
g_target PLS_INTEGER := c_table;
|
|
g_file VARCHAR2(2000) := 'err.log';
|
|
g_dir VARCHAR2(2000) := '/export/home/mcdonald/INBOX';
|
|
|
|
PROCEDURE pl(p_msg VARCHAR2) IS
|
|
l_start NUMBER := 1;
|
|
l_len CONSTANT NUMBER := 255;
|
|
BEGIN
|
|
WHILE l_start <= length(p_msg) LOOP
|
|
dbms_output.put_line(substr(p_msg
|
|
,l_start
|
|
,l_len));
|
|
l_start := l_start + l_len;
|
|
END LOOP;
|
|
END pl;
|
|
|
|
PROCEDURE who_called_me(p_owner OUT VARCHAR2
|
|
,p_name OUT VARCHAR2
|
|
,p_lineno OUT NUMBER
|
|
,p_caller_type OUT VARCHAR2
|
|
,p_helper_call_level IN NUMBER := 0) AS
|
|
l_call_stack VARCHAR2(4096) DEFAULT dbms_utility.format_call_stack;
|
|
l_num NUMBER;
|
|
l_found_stack BOOLEAN DEFAULT FALSE;
|
|
l_line VARCHAR2(255);
|
|
l_handle VARCHAR2(20);
|
|
l_linenum NUMBER;
|
|
l_count NUMBER := 0;
|
|
l_required_stack_level NUMBER := 5;
|
|
BEGIN
|
|
--
|
|
l_required_stack_level := l_required_stack_level + p_helper_call_level;
|
|
|
|
LOOP
|
|
l_num := instr(l_call_stack
|
|
,chr(10));
|
|
EXIT WHEN(l_count = l_required_stack_level OR l_num IS NULL OR
|
|
l_num = 0);
|
|
--
|
|
l_line := substr(l_call_stack
|
|
,1
|
|
,l_num - 1);
|
|
l_call_stack := substr(l_call_stack
|
|
,l_num + 1);
|
|
--
|
|
IF (NOT l_found_stack) THEN
|
|
IF (l_line LIKE '%handle%number%name%') THEN
|
|
l_found_stack := TRUE;
|
|
END IF;
|
|
ELSE
|
|
l_count := l_count + 1;
|
|
-- l_count = 1 is ME
|
|
-- l_count = 2 is MY Caller
|
|
-- l_count = 3 is Their Caller, etc
|
|
IF (l_count = l_required_stack_level) THEN
|
|
l_line := ltrim(l_line);
|
|
-- handle is the first part
|
|
l_handle := substr(l_line
|
|
,1
|
|
,instr(l_line
|
|
,' '));
|
|
--
|
|
-- Now, remove the object handle, then the white space from the call.
|
|
l_line := substr(l_line
|
|
,length(l_handle) + 1);
|
|
l_line := ltrim(l_line);
|
|
-- Now we can get the line number.
|
|
l_linenum := to_number(substr(l_line
|
|
,1
|
|
,instr(l_line
|
|
,' ')));
|
|
-- Remove the line number, and white space.
|
|
l_line := substr(l_line
|
|
,length(l_linenum) + 1);
|
|
l_line := ltrim(l_line);
|
|
|
|
IF (l_line LIKE 'pr%') THEN
|
|
l_num := length('procedure ');
|
|
ELSIF (l_line LIKE 'fun%') THEN
|
|
l_num := length('function ');
|
|
ELSIF (l_line LIKE 'package body%') THEN
|
|
l_num := length('package body ');
|
|
ELSIF (l_line LIKE 'pack%') THEN
|
|
l_num := length('package ');
|
|
ELSIF (l_line LIKE 'anonymous%') THEN
|
|
l_num := length('anonymous block ');
|
|
ELSE
|
|
l_num := NULL;
|
|
END IF;
|
|
IF (l_num IS NOT NULL) THEN
|
|
p_caller_type := ltrim(rtrim(upper(substr(l_line
|
|
,1
|
|
,l_num - 1))));
|
|
ELSE
|
|
p_caller_type := 'TRIGGER';
|
|
END IF;
|
|
|
|
l_line := substr(l_line
|
|
,nvl(l_num
|
|
,1));
|
|
l_num := instr(l_line
|
|
,'.');
|
|
p_owner := ltrim(rtrim(substr(l_line
|
|
,1
|
|
,l_num - 1)));
|
|
p_name := ltrim(rtrim(substr(l_line
|
|
,l_num + 1)));
|
|
p_lineno := l_linenum;
|
|
END IF;
|
|
END IF;
|
|
END LOOP;
|
|
END who_called_me;
|
|
|
|
PROCEDURE get_exception_message(p_exception_number IN exception_messages.exception_number%TYPE
|
|
,p_message IN OUT exception_messages.message%TYPE
|
|
,p_exme_type IN OUT exception_messages.exme_type%TYPE
|
|
,p_substitution_list IN g_t_substitution_list := c_empty_substitution_list) IS
|
|
l_index PLS_INTEGER;
|
|
l_err_msg VARCHAR2(512);
|
|
l_err_error VARCHAR2(1);
|
|
l_err_msg_type VARCHAR2(3);
|
|
l_err_msgid INTEGER;
|
|
l_err_loc VARCHAR2(240);
|
|
BEGIN
|
|
|
|
BEGIN
|
|
SELECT to_char(abs(exception_number)) || ': ' || message
|
|
,exme_type
|
|
INTO p_message
|
|
,p_exme_type
|
|
FROM exception_messages
|
|
WHERE exception_number = p_exception_number;
|
|
EXCEPTION
|
|
WHEN no_data_found THEN
|
|
p_message := 'UNABLE TO FIND MESSAGE FOR EXCEPTION ' ||
|
|
to_char(p_exception_number);
|
|
p_exme_type := 'E';
|
|
END;
|
|
|
|
l_index := p_substitution_list.FIRST;
|
|
|
|
LOOP
|
|
EXIT WHEN l_index IS NULL;
|
|
p_message := REPLACE(p_message
|
|
,'<p' || l_index || '>'
|
|
,p_substitution_list(l_index));
|
|
l_index := p_substitution_list.NEXT(l_index);
|
|
END LOOP;
|
|
|
|
END get_exception_message;
|
|
|
|
PROCEDURE log(p_exception_number IN PLS_INTEGER := NULL
|
|
,p_exception_message IN VARCHAR2 := NULL
|
|
,p_substitution_list IN g_t_substitution_list := c_empty_substitution_list
|
|
,p_helper_call_level IN NUMBER := 0
|
|
,p_error_group IN VARCHAR2 := 'APPLICATION'
|
|
,p_severity IN VARCHAR2 := 'E'
|
|
,p_source IN VARCHAR2 := NULL) IS
|
|
PRAGMA AUTONOMOUS_TRANSACTION;
|
|
l_exception_number PLS_INTEGER := nvl(p_exception_number
|
|
,SQLCODE);
|
|
l_exception_message exception_messages.message%TYPE;
|
|
l_exme_type exception_messages.exme_type%TYPE := substr(p_severity
|
|
,1
|
|
,1);
|
|
l_owner VARCHAR2(240);
|
|
l_name VARCHAR2(240);
|
|
l_lineno NUMBER;
|
|
l_caller_type VARCHAR2(240);
|
|
|
|
BEGIN
|
|
|
|
IF p_exception_number BETWEEN - 20999 AND - 20001 THEN
|
|
--
|
|
-- application error, see if we have a matching EXCEPTION_MESSAGE
|
|
--
|
|
get_exception_message(p_exception_number => l_exception_number
|
|
,p_substitution_list => p_substitution_list
|
|
,p_message => l_exception_message
|
|
,p_exme_type => l_exme_type);
|
|
l_exception_message := nvl(l_exception_message
|
|
,p_exception_message);
|
|
ELSE
|
|
l_exception_message := nvl(p_exception_message
|
|
,SQLERRM);
|
|
END IF;
|
|
IF p_source IS NULL THEN
|
|
who_called_me(p_owner => l_owner
|
|
,p_name => l_name
|
|
,p_lineno => l_lineno
|
|
,p_caller_type => l_caller_type
|
|
,p_helper_call_level => p_helper_call_level);
|
|
END IF;
|
|
|
|
IF g_target = c_table THEN
|
|
INSERT INTO error_logs
|
|
(erlo_id
|
|
,error_type
|
|
,SOURCE
|
|
,severity
|
|
,ERROR_CODE
|
|
,error_message
|
|
,error_date
|
|
,error_status
|
|
,call_stack
|
|
,backtrace
|
|
,error_stack
|
|
,created_on
|
|
,created_by
|
|
,updated_on
|
|
,updated_by)
|
|
VALUES
|
|
(erlo_seq.NEXTVAL
|
|
,p_error_group
|
|
,nvl(p_source
|
|
,l_name || ' line ' || l_lineno)
|
|
,l_exme_type
|
|
,l_exception_number
|
|
,l_exception_message
|
|
,SYSDATE
|
|
,'N'
|
|
,dbms_utility.format_call_stack
|
|
,dbms_utility.format_error_backtrace
|
|
,dbms_utility.format_error_stack
|
|
,SYSDATE
|
|
,0
|
|
,SYSDATE
|
|
,0);
|
|
|
|
pl('Error log:' || l_caller_type || ',' || l_name || ',' || l_lineno || ',' ||
|
|
l_exme_type || ',' || l_exception_number || ',' ||
|
|
l_exception_message || ',' ||
|
|
to_char(SYSDATE
|
|
,'mm/dd/yyyy hh24:mi:ss'));
|
|
|
|
ELSIF g_target = c_file THEN
|
|
DECLARE
|
|
fid utl_file.file_type;
|
|
BEGIN
|
|
fid := utl_file.fopen(g_dir
|
|
,g_file
|
|
,'A');
|
|
utl_file.put_line(fid
|
|
,'Error log:' || p_error_group || ',' ||
|
|
l_caller_type || ',' || l_name || ',' ||
|
|
l_lineno || ',' || l_exme_type || ',' ||
|
|
l_exception_number || ',' || l_exception_message || ',' ||
|
|
to_char(SYSDATE
|
|
,'mm/dd/yyyy hh24:mi:ss'));
|
|
utl_file.fclose(fid);
|
|
EXCEPTION
|
|
WHEN OTHERS THEN
|
|
utl_file.fclose(fid);
|
|
END;
|
|
ELSIF g_target = c_screen THEN
|
|
dbms_output.put_line('Error log:' || p_error_group || ',' ||
|
|
l_caller_type || ',' || l_name || ',' ||
|
|
l_lineno || ',' || l_exme_type || ',' ||
|
|
l_exception_number || ',' ||
|
|
l_exception_message || ',' ||
|
|
to_char(SYSDATE
|
|
,'mm/dd/yyyy hh24:mi:ss'));
|
|
|
|
END IF;
|
|
COMMIT;
|
|
EXCEPTION
|
|
WHEN OTHERS THEN
|
|
dbms_output.put_line(substr(SQLERRM
|
|
,1
|
|
,80));
|
|
ROLLBACK;
|
|
END;
|
|
|
|
PROCEDURE logto(p_target IN PLS_INTEGER
|
|
,p_dir IN VARCHAR2 := NULL
|
|
,p_file IN VARCHAR2 := NULL) IS
|
|
BEGIN
|
|
g_target := p_target;
|
|
g_file := nvl(p_file
|
|
,g_file);
|
|
g_dir := nvl(p_dir
|
|
,g_dir);
|
|
END;
|
|
|
|
FUNCTION logging_to RETURN PLS_INTEGER IS
|
|
BEGIN
|
|
RETURN g_target;
|
|
END;
|
|
|
|
PROCEDURE RAISE(p_exception_number IN PLS_INTEGER := NULL
|
|
,p_exception_message IN VARCHAR2 := NULL
|
|
,p_substitution_list IN g_t_substitution_list := c_empty_substitution_list) IS
|
|
l_exception_number PLS_INTEGER := nvl(p_exception_number
|
|
,SQLCODE);
|
|
l_exception_message VARCHAR2(1000) := nvl(p_exception_message
|
|
,SQLERRM);
|
|
l_exme_type exception_messages.exme_type%TYPE;
|
|
BEGIN
|
|
IF l_exception_number BETWEEN - 20999 AND - 20000 THEN
|
|
get_exception_message(p_exception_number => l_exception_number
|
|
,p_substitution_list => p_substitution_list
|
|
,p_message => l_exception_message
|
|
,p_exme_type => l_exme_type);
|
|
|
|
l_exception_message := nvl(l_exception_message
|
|
,p_exception_message);
|
|
|
|
raise_application_error(l_exception_number
|
|
,l_exception_message); /* Use positive error numbers -- lots to choose from! */
|
|
ELSIF l_exception_number > 0
|
|
AND l_exception_number NOT IN (1, 100) THEN
|
|
raise_application_error(-20000
|
|
,l_exception_number || '-' ||
|
|
l_exception_message); /* Can't EXCEPTION_INIT -1403 */
|
|
ELSIF l_exception_number IN (100, -1403) THEN
|
|
RAISE no_data_found; /* Re-raise any other exception. */
|
|
ELSIF l_exception_number != 0 THEN
|
|
EXECUTE IMMEDIATE 'DECLARE myexc EXCEPTION; ' ||
|
|
' PRAGMA EXCEPTION_INIT (myexc, ' ||
|
|
to_char(l_exception_number) || ');' ||
|
|
'BEGIN RAISE myexc; END;';
|
|
END IF;
|
|
END;
|
|
|
|
PROCEDURE handle(p_exception_number IN PLS_INTEGER := NULL
|
|
,p_exception_message IN VARCHAR2 := NULL
|
|
,p_substitution_list IN g_t_substitution_list := c_empty_substitution_list
|
|
,p_logerr IN BOOLEAN := TRUE
|
|
,p_reraise IN BOOLEAN := FALSE
|
|
,p_helper_call_level IN NUMBER := 0
|
|
,p_error_group IN VARCHAR2 := 'APPLICATION'
|
|
,p_severity IN VARCHAR2 := 'E'
|
|
,p_source IN VARCHAR2 := NULL) IS
|
|
BEGIN
|
|
IF p_logerr THEN
|
|
log(p_exception_number
|
|
,p_exception_message
|
|
,p_substitution_list
|
|
,p_helper_call_level => p_helper_call_level
|
|
,p_error_group => p_error_group
|
|
,p_severity => p_severity
|
|
,p_source => p_source);
|
|
END IF;
|
|
IF p_reraise THEN
|
|
cout_err.RAISE(p_exception_number
|
|
,p_exception_message
|
|
,p_substitution_list);
|
|
END IF;
|
|
END;
|
|
|
|
PROCEDURE report_and_stop(p_exception_number IN INTEGER := SQLCODE
|
|
,p_exception_message IN VARCHAR2 := NULL
|
|
,p_substitution_list IN g_t_substitution_list := c_empty_substitution_list
|
|
,p_helper_call_level IN NUMBER := 0
|
|
,p_error_group IN VARCHAR2 := 'APPLICATION'
|
|
,p_severity IN VARCHAR2 := 'E'
|
|
,p_source IN VARCHAR2 := NULL) IS
|
|
BEGIN
|
|
handle(p_exception_number
|
|
,p_exception_message
|
|
,p_substitution_list
|
|
,TRUE
|
|
,TRUE
|
|
,p_helper_call_level => p_helper_call_level
|
|
,p_error_group => p_error_group
|
|
,p_severity => p_severity
|
|
,p_source => p_source);
|
|
END report_and_stop;
|
|
|
|
PROCEDURE report_and_go(p_exception_number IN INTEGER := SQLCODE
|
|
,p_exception_message IN VARCHAR2 := NULL
|
|
,p_substitution_list IN g_t_substitution_list := c_empty_substitution_list
|
|
,p_helper_call_level IN NUMBER := 0
|
|
,p_error_group IN VARCHAR2 := 'APPLICATION'
|
|
,p_severity IN VARCHAR2 := 'E'
|
|
,p_source IN VARCHAR2 := NULL) IS
|
|
BEGIN
|
|
handle(p_exception_number
|
|
,p_exception_message
|
|
,p_substitution_list
|
|
,TRUE
|
|
,FALSE
|
|
,p_helper_call_level => p_helper_call_level
|
|
,p_error_group => p_error_group
|
|
,p_severity => p_severity
|
|
,p_source => p_source);
|
|
END report_and_go;
|
|
|
|
FUNCTION about RETURN VARCHAR2 IS
|
|
BEGIN
|
|
RETURN g_header;
|
|
END about;
|
|
|
|
END cout_err;
|
|
/
|