=== [[Ada (programming language)|Ada]] ===
with Ada.Exceptions; use Ada.Exceptions;
Exception declarations
:
Exceptions are declared rather like objects, but they are not objects. For example, recursive re-entry to a scope where an exception is declared does ''not'' create a new exception of the same name; instead the exception declared in the outer invocation is reused.
Ex.1
Line_Failed : {{Ada/kw|exception}};
Ex.2
{{Ada/kw|package}} Directory_Enquiries {{Ada/kw|is}}
procedure Foo is
{{Ada/kw|procedure}} Insert (New_Name : {{Ada/kw|in}} Name;
begin
New_Number : {{Ada/kw|in}} Number);
:
-- Start of exception declaration
{{Ada/kw|procedure}} Lookup (Given_Name : {{Ada/kw|in}} Name;
exception
Corr_Number : {{Ada/kw|out}} Number);
when Constraint_Error =>
-- Handle constraint error
Name_Duplicated : {{Ada/kw|exception}};
when Storage_Error =>
Name_Absent : {{Ada/kw|exception}};
-- Directory_FullPropagate the :Storage_Error as different {{Ada/kw|exception}};
raise Some_Error;
when Error : others =>
{{Ada/kw|end}} Directory_Enquiries;
-- Handle all others
Raising exceptions
The '''raise''' statement explicitly raises a specified exception.
Ex. 1
{{Ada/kw|package}} {{Ada/kw|body}} Directory_Enquiries {{Ada/kw|is}}
{{Ada/kw|procedure}} Insert (New_Name : {{Ada/kw|in}} Name;
New_Number : {{Ada/kw|in}} Number)
{{Ada/kw|is}}
…
{{Ada/kw|begin}}
…
{{Ada/kw|if}} New_Name = Old_Entry.A_Name {{Ada/kw|then}}
{{Ada/kw|raise}} Name_Duplicated;
{{Ada/kw|end}} {{Ada/kw|if}};
…
New_Entry := {{Ada/kw|new}} Dir_Node'(New_Name, New_Number,…);
…
{{Ada/kw|exception}}
{{Ada/kw|when}} Storage_Error => {{Ada/kw|raise}} Directory_Full;
{{Ada/kw|end}} Insert;
{{Ada/kw|procedure}} Lookup (Given_Name : {{Ada/kw|in}} Name;
Corr_Number : {{Ada/kw|out}} Number)
{{Ada/kw|is}}
…
{{Ada/kw|begin}}
…
{{Ada/kw|if}} {{Ada/kw|not}} Found {{Ada/kw|then}}
{{Ada/kw|raise}} Name_Absent;
{{Ada/kw|end}} {{Ada/kw|if}};
…
{{Ada/kw|end}} Lookup;
{{Ada/kw|end}} Directory_Enquiries;
Exception handling and propagation
Exception handlers may be grouped at the end of a block, subprogram body, etc. A handler is any sequence of statements that may end:
* by completing;
* by executing a '''return''' statement;
* by raising a different exception ('''raise''' e;);
* by re-raising the same exception ('''raise''';).
Suppose that an exception ''e'' is raised in a sequence of statements ''U'' (a block, subprogram body, etc.).
* If ''U'' contains a handler for ''e'': that handler is executed, then control leaves ''U''.
* If ''U'' contains no handler for ''e'': ''e'' is ''propagated'' out of ''U''; in effect, ''e'' is raised at the "point of call” of ''U''.
So the raising of an exception causes the sequence of statements responsible to be abandoned at the point of occurrence of the exception. It is not, and cannot be, resumed.
Ex. 1
...
{{Ada/kw|exception}}
{{Ada/kw|when}} Line_Failed =>
{{Ada/kw|begin}} {{Ada/--|attempt recovery}}
Log_Error;
Retransmit (Current_Packet);
{{Ada/kw|exception}}
{{Ada/kw|when}} Line_Failed =>
Notify_Engineer; {{Ada/--|recovery failed!}}
Abandon_Call;
{{Ada/kw|end}};
...
Information about an exception occurrence
Ada provides information about an exception in an object of type Exception_Occurrence, defined in {{Ada/package|Ada.Exceptions}} along with subprograms taking this type as parameter:
* Exception_Name: return the full exception name using the dot notation and in uppercase letters. For example, <tt>Queue.Overflow</tt>.
* Exception_Message: return the exception message associated with the occurrence.
* Exception_Information: return a string including the exception name and the associated exception message.
For getting an exception occurrence object the following syntax is used:
{{Ada/kw|with}} {{Ada/package 2|Ada|Exceptions}}; {{Ada/kw|use}} {{Ada/package 2|Ada|Exceptions}};
...
{{Ada/kw|exception}}
{{Ada/kw|when}} Error: High_Pressure | High_Temperature =>
Put ("Exception: ");
Put_Line (Exception_Name (Error));
Put (Exception_Message (Error));
end;
{{Ada/kw|when}} Error: {{Ada/kw|others}} =>
Put ("Unexpected exception: ");
Put_Line (Exception_Information(Error));
{{Ada/kw|end}};
The exception message content is implementation defined when it is not set by the user who raises the exception. It usually contains a reason for the exception and the raising ___location.
The user can specify a message using the procedure Raise_Exception.
{{Ada/kw|declare}}
Valve_Failure : {{Ada/kw|exception}};
{{Ada/kw|begin}}
...
Raise_Exception (Valve_Failure'{{Ada/attribute|Identity}}, "Failure while opening");
...
Raise_Exception (Valve_Failure'{{Ada/attribute|Identity}}, "Failure while closing");
...
{{Ada/kw|exception}}
{{Ada/kw|when}} Fail: Valve_Failure =>
Put (Exceptions_Message (Fail));
{{Ada/kw|end}};
The package also provides subprograms for saving exception occurrences and reraising them.
For a more complete discussion of exceptions in Ada see [[:Wikibooks:Ada Programming/Exceptions|the wikibook on Ada]].
|