Oracle Repository API and Model Reference Guide


Contents


API Methods


Element Definitions


Index  


Error Handling Example

See also:

CDAPI Activities for background explanation of the CDAPI activities mechanism.

The following example code illustrates the use of activity mechanism to handle the trapping and reporting of errors during a PL/SQL insert operation.

Notes:

  1. The BUSINESS_OBJECT element type shown in this example is new in Release 6i of Oracle Repository.

  2. Three sources of error messages are inspected in this example:

    Callers (clients) receive error messages from all three sources.

  3. Only one activity is shown. Activities can be nested. If an outer activity is aborted, database operations in that activity and in any inner activities are all rolled back.

  4. Once an activity has successfully closed all entries in CI_VIOLATIONS are removed. The only way to check for warning errors separately from other errors is with a call to validate_activity.

Example

REM
***************************************************************************
REM Insert Business Object test script created on 29-JUN-99
REM
***************************************************************************

DECLARE
bob ciobusiness_object.data;
act_status varchar2 (100);
act_warnings varchar2 (100);
line varchar2 (240);
procedure o (text varchar2) is
begin
dbms_output.put_line (substr (text, 1,255));
end;
BEGIN
-- Initialize the API and establish a context container,
-- if not already done
-- assumes a context workarea has been set... --
if not cdapi.initialized then
         o ('Initializing the API');
         cdapi.initialize (upper ('&&context_container'));
end if;

-- Open a new activity
o ('Opening a new activity');
cdapi.open_activity;

-- Get the insert values into the property list of the new element
bob.v.ENTITY_OBJECT_REFERENCE := '&ENTITY_OBJECT_REFERENCE';
if bob.v.ENTITY_OBJECT_REFERENCE is not null then
               bob.i.ENTITY_OBJECT_REFERENCE := true;
end if;

bob.v.GENERIC_CLASS_REFERENCE := '&GENERIC_CLASS_REFERENCE';
if bob.v.GENERIC_CLASS_REFERENCE is not null then
               bob.i.GENERIC_CLASS_REFERENCE := true;
end if;

bob.v.IRID := '&IRID';
if bob.v.IRID is not null then
                bob.i.IRID := true;
end if;

bob.v.IVID := '&IVID';
if bob.v.IVID is not null then
                bob.i.IVID := true;
end if;

bob.v.NAME := '&NAME';
if bob.v.NAME is not null then
                bob.i.NAME := true;
end if;

-- Nest all element operations in anonymous blocks to catch exceptions
-- Since all exceptions signal a fatal error with the operation, rollback
-- all database activity performed by the operation

-- Perform the INSERT operation within an anonymous block
declare
ci_savepoint varchar2 (10);
begin
        ci_savepoint := 'CI' || to_char (sysdate,'HH:MI:SS');
        -- Issue a savepoint to rollback to if an exception is raised
        dbms_transaction.savepoint (ci_savepoint);
        o ('Inserting a new Business Object');
        ciobusiness_object.ins (null,bob);
        -- CDAPI methods can cause the CI_VIOLATIONS view to be populated with
        -- constraints violations caused by errors in the
        -- make-up of the element (intra-element violations), so we could at
        -- this point query the CI_VIOLATIONS view.
        -- The view can be queried at any time, but only validate_activity
        -- populates it with inter-element constraints
        -- violation errors as well as intra-element constraints violation errors.
        -- exception handler for inner block
exception
        -- If an unhandled exception was raised during the operation, rollback
        -- to the savepoint and print out any messages that are on the
        -- PL/SQL and API stacks
when others then
        -- Display PL/SQL errors
        o ('1** Printing PL/SQL error stack ***');
        o (dbms_utility.format_error_stack);
        o ('***********************************');
        o ('Operation aborted due to unhandled exceptions');
        dbms_transaction.rollback_savepoint (ci_savepoint);
        -- Display CDAPI errors
        while cdapi.stacksize > 0 loop
                o (cdapi.pop_instantiated_message);
                -- Any errors would have been posted by the CDAPI code
        end loop;
end;

-- Print the (interesting) properties in the property list which hold values

if bob.v.BUSINESS_OBJECT_TOP is not null then
        o ('BUSINESS_OBJECT_TOP : '||bob.v.BUSINESS_OBJECT_TOP);
end if;
if bob.v.ENTITY_OBJECT_REFERENCE is not null then
        o ('ENTITY_OBJECT_REFERENCE : '||bob.v.ENTITY_OBJECT_REFERENCE);
end if;
        if bob.v.GENERIC_CLASS_REFERENCE is not null then
        o ('GENERIC_CLASS_REFERENCE : '||bob.v.GENERIC_CLASS_REFERENCE);
end if;
if bob.v.ID is not null then
        o ('ID : '||bob.v.ID);
end if;
if bob.v.IRID is not null then
        o ('IRID : '||bob.v.IRID);
end if;
if bob.v.IVID is not null then
        o ('IVID : '||bob.v.IVID);
end if;
if bob.v.NAME is not null then
        o ('NAME : '||bob.v.NAME);
end if;

-- Validate the activity to reveal outstanding constraint violations. Validate_activity can be called at any time to
-- do an interim check on progress so far. This is one of the
-- advantages of the CDAPI activity mechanism over SQL transactions.
--
-- We are doing this here because we want to display (but not act on) ALL errors that have been placed in
-- the CI_VIOLATIONS view. That is, we are
--
-- validate_activity also traps inter-element constraint violations,
-- not just intra-element constraint violations
-- (that is, violations resulting from conflicts between the element we are
-- inserting and other elements - for example,
-- if we've given it a name that is not unique within its container).
cdapi.validate_activity (act_status,act_warnings);

-- The following loop queries the CI_VIOLATIONS view and reports all database violations.
-- act_status isn't actually tested here,
-- but should be. If = 'Y' on return, there are errors rows in the CI_VIOLATIONS view.
--
for viol in (select * from ci_violations) loop
        if viol.warning='Y' then
        line:='WNG: ';
        else
                line:='ERR: ';
        end if;
        o (line||cdapi.instantiate_message (viol.facility,viol.code,
        viol.p0,viol.p1,viol.p2,viol.p3,viol.p4,viol.p5,viol.p6,viol.p7));
end loop;

-- Report any non-fatal messages that might have been posted on the CDAPI stack by the API code
while cdapi.stacksize > 0 loop
        o (cdapi.pop_instantiated_message);
end loop;
--
-- Attempt to close the activity. close_activity is a request to try to close the activity.
-- The API does not close the activity if there are rows in the CI_VIOLATIONS view;
-- on return, the parameter act_status will contain 'N' to indicate that the activity could not be closed
-- and that CI_VIOLATIONS is not empty.
--
-- We are doing this here because since the call to validate_activity, the state of the
-- repository may have changed in such a way as to give rise to inter-element constraint violations.
-- (close_activity implicitly calls validate_activity. )
cdapi.close_activity (act_status);
-- If the status !=Y, then abort the activity.
-- We could do all manner of things here, but in this test we
-- choose to abort the attempt to insert the new element.
-- One strategy would be to continue to fix the errors
-- and continuously try to insert the object, testing for violations each time.
if act_status != 'Y' then
        cdapi.abort_activity;
        o ('Activity aborted with constraint violations');
-- Otherwise, the activity closed successfully
else
        o ('Activity closed successfully');
end if;
-- exception handler for outer block
EXCEPTION
-- Catch all exceptions
when others then
        -- Print the PL/SQL error stack
        o ('2** Printing PL/SQL error stack ***');
        o (dbms_utility.format_error_stack);
        o ('***********************************');
        -- Are there messages on the CDAPI stack?
        if cdapi.stacksize > 0 then
                -- Print all messages on the CDAPI stack
                while cdapi.stacksize > 0 loop
                        o (cdapi.pop_instantiated_message);
                end loop;
                -- If there is currently an open activity, abort it now
                if cdapi.activity is not null then
                        cdapi.abort_activity;
                o ('Activity aborted with API errors');
                else
                        o ('API Session aborted with API errors');
                end if;
        -- If there are no messages on the CDAPI stack, this was a non-CDAPI exception
        else
        -- If there is currently an open activity, abort it now
                if cdapi.activity is not null then
                        cdapi.abort_activity;
                        o ('Activity aborted with ORACLE internal errors');
                else
                o ('API Session aborted with API errors');
                end if;
        end if;
END; 

Note on the dbms_utility package:

dbms_utility is one of the standard PL/SQL supplied packages (see the section on Supplied Packages in the Oracle8 Application Developer's Guide ).

The format of a call to dbms_utility.format_error_stack is:

    function format_error_stack return varchar2; 

Format the current error stack. This can be used in exception handlers to look at the complete error stack.

Return to Top