Skip to content

G-5080: Always use FORMAT_ERROR_BACKTRACE when using FORMAT_ERROR_STACK or SQLERRM.

Minor

Maintainability, Testability

Reason

In exception handler sqlerrm and format_error_stack won't tell you the exact line where the error occurred. format_error_backtrace displays the call stack at the point where an exception was raised, even if the subprogram is called from an exception handler in an outer scope.

If you use sqlerrm or format_error_stack to log/display error, you should also include format_error_backtrace to identify the exact location where the exception was raised.

Example (bad)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
create or replace package body order_api as
   procedure discount_and_recalculate(
      in_customer_id    customer.id%type
    , in_discount       customer.discount_percentage%type
   )
   begin
      customer_api.apply_discount(in_customer_id, in_discount);
      customer_api.in_customer_id(10293847);
   exception
      when zero_divide then
         null; -- ignore
      when others then
         logging_package.log_error('Error: ' || sqlerrm);
         raise;
   end discount_and_recalculate;
end order_api;
/

Example (good)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
create or replace package body order_api as
   procedure discount_and_recalculate(
      in_customer_id    customer.id%type
    , in_discount       customer.discount_percentage%type
   )
   begin
      customer_api.apply_discount(in_customer_id, in_discount);
      customer_api.in_customer_id(10293847);
   exception
      when zero_divide then
         null; -- ignore
      when others then
         logging_package.log_error(
            'Error: ' || sqlerrm || ' - Backtrace: ' || dbms_utility.format_error_backtrace
         );
         raise;
   end discount_and_recalculate;
end order_api;
/