API Exceptions (was: Re: Looking for an elegant way to convert
API methods throwing exceptions to new API methods returning codes)
On 09.11.2011 07:45, A. McKenney wrote:
On Nov 8, 3:17 am, "Martin B."<0xCDCDC...@gmx.at> wrote:
On 06.11.2011 09:45, A. McKenney wrote:
....
It is much harder to write code that does _not_ leak resources if you
have to worry about exceptions. Nobody had to worry about exception
safety before exceptions were introduced. Exceptions simply added more
possible ways to leak resources, (...)
Ah. The good old times of no exceptions! (*)
If you interpret "Good old days" as being
sort of like the "good old days" of driving
on Afghan "highways" before the days of IEDs.
I should have put the <cynicism> tags in there :-)
So you're a fan of code like this?:
developer.mozilla.org/En/Mozilla_Coding_Style_Guide#Use_the_nice_macros
Not exactly a fan, but I found myself writing
very similar code when using an API that threw
exceptions whenever it got what it considered
an error.
Well, actually, it was worse. Every API call had
to be enclosed in a try/catch, because otherwise
there was no way to tell what step had failed,
and thus no way to even know where to look to
find out what was wrong or how to recover. In
this case, exceptions offered no advantage over
error codes, except, of course, that they chewed
up more CPU.
If I sound a bit disenchanted with
exceptions, it's because this case is
rather typical of my experience with code
that uses exceptions.
Well, "a bit" is probably not strong enough for how your statement
sounded to me :-)
What you describe is either a case of
a) really crappy API design wrt. exceptions -- can we blame exceptions
for that? Not sure. (It's possible though, afaic.)
b) Getting the code backwards. You write:
Every API call had
to be enclosed in a try/catch,
because otherwise there was no
way to tell what step had failed,
and thus no way to even know where
to look to find out what was
wrong or how to recover.
Which *could* be code like that:
try {
conn.open(...);
} catch(APIEx const& e) {
handle_error(e, CONNECTION_OPEN_FAILED);
return;
}
try {
conn.read_data(...);
} catch(APIEx const& e) {
handle_error(e, CONN_DATAREAD_FAILED);
return;
}
// ::: etc.
Now, what I found works better is:
connection_state x(PRE_OPEN);
try {
conn.open(...);
x = OPENED;
conn.read_data(...);
x = DATA_READ;
// ::: etc.
} catch(APIEx const& e) {
handle_error(x, e);
return; // maybe
}
that is, if I need to, I keep track of the state in a separate object
(or more often only via log lines) and when an exception happens, I know
exactly where.
Does that make sense?
cheers,
Martin
--
I'm here to learn, you know.
Just waiting for someone,
to jump from the shadows,
telling me why I'm wrong.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]