Ada: Exceptions

Ada's exception mechanism reports and recovers from run-time failures with named, catchable events. Every automatic check in the language — ranges, bounds, division by zero, null access — raises a named exception at the exact point of failure. Nothing fails silently.

Raise and Handle

Exceptions are ordinary declared objects. raise signals one; a block's exception part handles it:

with Ada.Text_IO; use Ada.Text_IO;

procedure Exception_Demo is
   Overflow : exception;                     -- a user-defined exception

   function Divide (A, B : Integer) return Integer is
   begin
      if B = 0 then
         raise Overflow with "division by zero requested";   -- attach a message
      end if;
      return A / B;
   end Divide;
begin
   Put_Line (Integer'Image (Divide (10, 0)));
exception                                      -- handler for THIS unit
   when E : Overflow =>
      Put_Line ("caught: " & Exception_Message (E));   -- "division by zero requested"
end Exception_Demo;

E : Overflow names the occurrence so the handler can read its message and identity (Exception_Identity (E) distinguishes occurrences of the same exception).

Propagation

An unhandled exception unwinds frames until some caller handles it. Code after the raise never runs in that frame:

Exception raised in Read_Input propagating through Read_Line to Main's handler
Fig. 1 — The raise unwinds frames until a handler matches; frames in between are cleanly exited.
procedure Propagation_Demo is
begin
   begin
      raise Constraint_Error;      -- simulate a failure
      Put_Line ("skipped");        -- never executes
   exception
      when Storage_Error => null;  -- not ours: propagates further out
   end;
   --  ...the inner handler did not match, so this point is never reached
   --  unless an OUTER handler catches what escaped.
end Propagation_Demo;

Predefined Exceptions

The language raises these automatically — you mostly handle them rather than raise them:

ExceptionRaised when
Constraint_Errora range, index, or null-exclusion check fails
Program_Errorcontrol reaches an impossible point (e.g. missing return)
Storage_Errorthe stack or heap is exhausted
Tasking_Errora task communication fails

Library packages define their own (Name_Error, Data_Error in I/O), always declared in the package's specification — check the spec to know what to catch.

others and Last-Resort Handlers

when others => catches everything; its legitimate home is a top-level handler that logs and reports. Using it deep in the code hides bugs:

   --  main program of a long-running system:
--  exception
--     when E : others =>
--        Log ("unhandled " & Exception_Name (E));   -- name, not just message
--        raise;                                     -- re-raise: never swallow

The bare raise; inside a handler re-raises the same occurrence — the standard idiom for "log and continue propagating." Next: Generics.