Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Common exception handling

0 views
Skip to first unread message

shaunpa...@gmail.com

unread,
Aug 26, 2008, 8:17:32 AM8/26/08
to
I'm wondering if there is a clean way to do something common for all
throw exceptions and then handle each exception. For exception...

procedure Test (Rec : Record) is
begin

... throw 3 possible exceptions...


exception
when A =>
Print_Test (Rec);
...
when B =>
Print_Test (Rec);
...
when C =>
Print_Test (Rec);
...
when others =>
Print_Test (Rec);
end Test;

I'd like to not duplicate the Print_Test in each situation. Is there
an easy way

Thanks,

Shaun

Ludovic Brenta

unread,
Aug 26, 2008, 8:37:45 AM8/26/08
to
procedure Test (Rec : Record) is
begin
... throw 3 possible exceptions...
exception
when A | B | C => Print_Test (Rec);
end Test;

--
Ludovic Brenta.

Martin

unread,
Aug 26, 2008, 8:39:23 AM8/26/08
to
On Aug 26, 1:17 pm, shaunpatter...@gmail.com wrote:
[snip]

> I'd like to not duplicate the Print_Test in each situation.  Is there
> an easy way

Just add an extra level of exception handling and re-raise the
exception when you've done the common bit:

with Ada.Text_IO; use Ada.Text_IO;

procedure Throw_Three is

type Record_Type is
record
I : Integer;
end record;

procedure Print_Test (Rec : Record_Type) is
begin
Put_Line ("Print_Test:" & Integer'Image (Rec.I));
end Print_Test;

A, B, C : exception;

procedure Test (Rec : Record_Type) is
begin
begin
case Rec.I is
when 1 => raise A;
when 2 => raise B;
when 3 => raise C;
when others => raise Program_Error;
end case;
exception
when others =>
Print_Test (Rec); -- Common bit
raise; -- Re-raise the same exception
end;
exception
when A =>
Put_Line ("A");
when B =>
Put_Line ("B");
when C =>
Put_Line ("C");
when others =>
Put_Line ("others");
end Test;
begin
for I in 1 .. 4 loop
Test (Rec => (I => I));
end loop;
end Throw_Three;

Ludovic Brenta

unread,
Aug 26, 2008, 8:48:56 AM8/26/08
to
Martin wrote:
> exception
> when A =>
> Put_Line ("A");
> when B =>
> Put_Line ("B");
> when C =>
> Put_Line ("C");
> when others =>
> Put_Line ("others");

If all you want it to print the name of the exception, it is better
like this:

exception
when E : others =>
Put_Line (Ada.Exceptions.Exception_Name (E));

--
Ludovic Brenta.

Martin

unread,
Aug 26, 2008, 8:58:54 AM8/26/08
to
On Aug 26, 1:48 pm, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
[snip]

> If all you want it to print the name of the exception, it is better
> like this:
>
> exception
>    when E : others =>
>       Put_Line (Ada.Exceptions.Exception_Name (E));
>
> --
> Ludovic Brenta.

Yes, it was just a method of demonstrating the different paths that
have been exercised.

Cheers
-- Martin

shaunpa...@gmail.com

unread,
Aug 26, 2008, 9:47:27 AM8/26/08
to
Yeah, it looks like the extra layer of exception handling is the only
way. I was hoping I could avoid that if possible.

Thanks,

--
Shaun

Adam Beneschan

unread,
Aug 26, 2008, 10:43:20 AM8/26/08
to
On Aug 26, 6:47 am, shaunpatter...@gmail.com wrote:
> Yeah, it looks like the extra layer of exception handling is the only
> way. I was hoping I could avoid that if possible.

No, I don't think it's the only way. I'm surprised no one has
suggested this:

exception
when E : others =>

Print_Test (Rec);
declare
use Ada.Exceptions;
begin
if Exception_Identity(E) = A'Identity then
... handling for A
elsif Exception_Identity(E) = B'Identity then
... handling for B
etc.
else
... handling for other exceptions you didn't expect,
... but you certainly need to aware that it could
... happen
raise; --maybe
end if;
end;

-- Adam

Dmitry A. Kazakov

unread,
Aug 26, 2008, 11:10:32 AM8/26/08
to

Hmm, it looks quite ugly, IMO. Exception handler (case-like) is better
structured, cleaner, and possibly more efficient.

---------
If exceptions were first-class citizens allowed in case statements then:

exception
when E : others =>
Print_Test (Rec);

case E is -- This is not Ada, alas!
when A => ...
when B => ...
when others => ...
end case;

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

Jean-Pierre Rosen

unread,
Aug 26, 2008, 11:18:59 AM8/26/08
to
shaunpa...@gmail.com a écrit :

> Yeah, it looks like the extra layer of exception handling is the only
> way. I was hoping I could avoid that if possible.
>
I guess this is what you want...

exception
when others =>
-- common part
...
begin
raise; -- Reraises current exception
exception


when A =>
...
when B =>
...

end;
end;

--
---------------------------------------------------------
J-P. Rosen (ro...@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr

Adam Beneschan

unread,
Aug 26, 2008, 12:49:59 PM8/26/08
to
On Aug 26, 8:10 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

Maybe this use of CASE should be allowed, even if we don't go all the
way and make exceptions first-class entities in other ways. What does
anyone else think... would it be a worthwhile feature to propose
adding? Or is it just too "special" (if we added this, others would
ask, well why shouldn't we allow CASE on a string, or a record, or a
container, or just expand it using some user-specified relational
operator so that we can use it for everything...)?

-- Adam

Dmitry A. Kazakov

unread,
Aug 26, 2008, 3:14:10 PM8/26/08
to
On Tue, 26 Aug 2008 09:49:59 -0700 (PDT), Adam Beneschan wrote:

> Maybe this use of CASE should be allowed, even if we don't go all the
> way and make exceptions first-class entities in other ways. What does
> anyone else think... would it be a worthwhile feature to propose
> adding? Or is it just too "special" (if we added this, others would
> ask, well why shouldn't we allow CASE on a string, or a record, or a
> container, or just expand it using some user-specified relational
> operator so that we can use it for everything...)?

Right, I fully agree. Ada is overloaded with "special" features.

I prefer exceptions become a "normal" discrete type (only in the interface
of). I wished to have ranges of exceptions so that one could define a group
of related exceptions, and be able to extend such groups. This could the
first step in order to make exceptions contracted.

There is a similar important case, the type tags. Tags and exceptions have
much in common. It would be very nice to find a generic mechanism for
handling such things. That would remove a lot of "magic" from the language,
IMO.

Maciej Sobczak

unread,
Aug 26, 2008, 4:22:03 PM8/26/08
to
On 26 Sie, 21:14, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

> I wished to have ranges of exceptions

Hierarchies, not ranges.

The difference is that entities in the hierarchy can be not only
extended but also specialized and that would nicely fit in the OO part
of the language.

> This could the
> first step in order to make exceptions contracted.

Yes.

Oh, wait. We have discussed that part already and there was no
conclusion. :-)

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada

Dmitry A. Kazakov

unread,
Aug 27, 2008, 4:16:40 AM8/27/08
to
On Tue, 26 Aug 2008 13:22:03 -0700 (PDT), Maciej Sobczak wrote:

> On 26 Sie, 21:14, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>
>> I wished to have ranges of exceptions
>
> Hierarchies, not ranges.

Yes, but it is still a range, technically, a bounded set. The problem is
that this set can be infinite. Such structure of an ordered set have real
numbers, strings, and, of course, type hierarchies.



> The difference is that entities in the hierarchy can be not only
> extended but also specialized and that would nicely fit in the OO part
> of the language.

Extension = specialization in classic OO (and Ada). When a type is extended
by adding new members and/or methods it is a specialization of the class
rooted in the derivation base.

Georg Bauhaus

unread,
Aug 27, 2008, 5:20:12 AM8/27/08
to
Maciej Sobczak schrieb:

> On 26 Sie, 21:14, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>
>> I wished to have ranges of exceptions
>
> Hierarchies, not ranges.
>
> The difference is that entities in the hierarchy can be not only
> extended but also specialized and that would nicely fit in the OO part
> of the language.

Meanwhile, using a nested programming language,
we can do

type Throwable is tagged private;
...

procedure Outer is
Fail: exception;

package OO_Exception is
type Relevant_Info is new Throwable with
-- everything needed to known what
-- has happened deep down the call chain
record
...
end record;
procedure Prim_Op(Recording: Relevant_Info);

end OO_Exception;

package body OO_Exception is separate;
use OO_Exception;

procedure Inner is
begin
...
end Inner;


Scrap_Book: Relevant_Info;

begin
Inner;
exception
when Fail =>
Prim_Op(Scrap_Book);
end Outer;

--
Georg Bauhaus
Y A Time Drain http://www.9toX.de

Martin

unread,
Aug 29, 2008, 4:32:18 AM8/29/08
to

Surely you missed a smiley off this suggestion!!! :-)

== Martin

Adam Beneschan

unread,
Aug 29, 2008, 11:31:03 AM8/29/08
to

Well, I do often post silly things without smileys and assume everyone
is astute enough to figure out that I was trying to be funny. But I
wasn't being funny here. Although the above looks somewhat ugly, I
can imagine that a solution of this sort may be entirely appropriate
in some cases. Suppose, for example, that the common code isn't just
at the beginning, but is also at the end, or maybe even in the middle;
the nested exception handler/reraise solution might not be so clean in
that case. Another problem with the nested exception handler solution
is that it could incur extra overhead since exception raising isn't
necessarily cheap. That shouldn't matter in most cases, but sometimes
it might. So I don't understand why the above is so ridiculous as to
merit the comment you gave.

I would say, though, that if your exception-handling code gets that
complex, it might be time to think about declaring just one exception
and a separate data structure for passing additional exception info
around.

-- Adam

Martin

unread,
Sep 10, 2008, 6:51:37 PM9/10/08
to

Sorry - back again!

It was mostly the (to my eyes) sheer "ugliness" of the
if..elsif..elsif..end if;.

I find these sorts of structures very hard to follow (was there a
sneeky 'and then <boolean_expression>' snuck into one of the
branches???

-- Martin

Adam Beneschan

unread,
Sep 11, 2008, 10:57:42 AM9/11/08
to

That sort of argues for an extended "case" statement that is just
syntactic sugar for a series of equality comparisons. (Dmitry alluded
to that up above.) Without changing the language, I suppose you could
turn each "case" branch into a procedure and set up a search table
that maps Exception_ID's into procedure accesses. Maybe that would be
a little less ugly. Both of these ideas would be essentially
equivalent to the if/elsif/elsif... but perhaps more aesthetic.

However, I do *not* think it's necessarily a good idea to change the
structure around just for aesthetic reasons. Using nested exception
handlers may look nicer, but to me this is a fundamentally different
control structure---which, as I mentioned, may break down if you also
have common code that needs to be performed *after* the specific code
for each exception. I'd rather write something that looks a bit ugly
than twist the code around to make it fit into a control structure
that doesn't do as good job of reflecting how I see the problem at
hand.

-- Adam


0 new messages