Oracle uses exception handler from first block in later blocks Oracle uses exception handler from first block in later blocks oracle oracle

Oracle uses exception handler from first block in later blocks


This seems to be a bug, which has (so far) been reproduced in 11.2.0.4, 12.1.0.2 and 12.2.0.1. It doesn't seem to require DDL, or any real action in the first sub-block (though just doing null; as a placeholder doesn't trigger it, possibly because the compiler removes it), but it does seem to need the if inside both exception handlers:

begin  begin    dbms_output.put_line('Dummy message');  exception    when others then      dbms_output.put_line('In first exception handler');      if 1=1 then        raise;      end if;  end;  begin    execute immediate 'invalid';  exception    when others then      dbms_output.put_line('In second exception handler');      if 1=1 then        raise;      end if;  end;end;/Dummy messageIn second exception handlerORA-00900: invalid SQL statementORA-06512: at line 8ORA-06512: at line 13

As with your example the exception is thrown by line 13 so should be reported as (re-)raised at line 18; but it's instead it's reported as raised from line 8, which doesn't make sense. (The at line 13 message is only shown in 12.2; in 11.2 and 12.1 it only reports the first ORA-06512, which is rather more confusing. At least in 12 2 you have some clue where the problem really is.)

From the debugs you can see it doesn't actually use the first exception handler, and it does go into the second one. It 'only' seems to be reporting against the wrong line number, rather than executing the wrong code.

It appears that doing real work inside the if, immediately before the raise somehow fixes things - in either exception handling section; this adds a message in the first, which can't be reached:

begin  begin    dbms_output.put_line('Dummy message');  exception    when others then      dbms_output.put_line('In first exception handler');      if 1=1 then        dbms_output.put_line('This avoids the bug somehow');        raise;      end if;  end;  begin    execute immediate 'invalid';  exception    when others then      dbms_output.put_line('In second exception handler');      if 1=1 then        raise;      end if;  end;end;/Dummy messageIn second exception handlerORA-00900: invalid SQL statementORA-06512: at line 19ORA-06512: at line 14

and this in the second:

begin  begin    dbms_output.put_line('Dummy message');  exception    when others then      dbms_output.put_line('In first exception handler');      if 1=1 then        raise;      end if;  end;  begin    execute immediate 'invalid';  exception    when others then      dbms_output.put_line('In second exception handler');      if 1=1 then        dbms_output.put_line('This avoids the bug somehow');        raise;      end if;  end;end;/Dummy messageIn second exception handlerORA-00900: invalid SQL statementORA-06512: at line 19ORA-06512: at line 13

In both cases the reported line number is now correct. Somehow.

It doesn't have to be a dbms_output call, anything seems to work, such as a dummy procedure call or query, even an extra sub-block (e.g. begin execute immediate 'select * from dual'; end;, even though the query isn't executed because there's no into...). Again just using null; doesn't work though.

This is a bit ugly but gives you a way to stop it from happening at least, sort of.

It's clearly weird and unexpected and inconsistent behaviour, and has been around for a while, so it should probably be raised as a service request through My Oracle Support. I can't see any existing reports but I didn't look very hard so there might be one lurking somewhere.