Re: Descriptive exceptions
* Eugene Gershnik:
On Feb 20, 6:58 pm, "Alf P. Steinbach" <a...@start.no> wrote:
* Eugene Gershnik:
[snippety-snip]
Why it's a good idea to have a human readable description: it's
sometimes useful and the standard functionality provides for it.
You contradict yourself here (I think). Creating, storing and copying
the description is expensive and that's what you wanted to avoid. Why
integral "message ID" is not good enough for you?
An integral message id might be good enough as an internal
representation within the exception object, depending on the context,
and it might even be a more or less required method in some context
(e.g., passing up library/API error codes, low-memory handling, although
the latter is IMHO better handled in other ways than by throwing
exceptions). But in the interest of treating exceptions uniformly,
what() should better produce an English descriptive text anyway; of
course it might produce that text by looking up an id. Applying
sensible uniform conventions lead to simpler systems and less work.
Why
it's a good idea to have that description in English: exception-carried
messages are meant for the programmer,
Who of course must speak English...
English is the lingua franca of software engineering. It's no fun to
work on source code and documentation partially in Norwegian, Swedish
(possible to understand for us Norwegians, but), Finnish (not possible,
unless you know Finnish), English and Icelandic. Which I've done.
By standardizing on English such problems are mostly avoided.
not the user, and supporting
national languages in standard C++ exceptions is a nightmare.
Did you actually try it? Just store an ID and translate when you need
the string (at catch point for example). Nobody forces you to use
what() (and you even can use what() pointer as an ID).
Yes, I've tried id's and nested exceptions and exception throwing as
expressions and automatically picking up Windows error codes and stack
traces and UTF-8 messages and passing exceptions via Corba and
translating to/from Windows COM and OLE Automation exceptions and
whatnot, you name it. It's been a long time... ;-) However, I'm
unaware of having discussed any of this in this thread, in particular, I
haven't to the best of my recollection discussed id schemes here (if
I've done so in clc++m it must have been many years ago, perhaps ten
years or so), so I'm not sure what you're arguing against, or for.
Now for the "as much internal information as you can" in the exception
itself. No, that isn't a good idea, and that's because of the reasons
snipped above: all that information is in most cases baggage of very
negative worth. It not only slows things down to collect it and copy
it, but collecting it and copying it can introduce additional failure
points and failure modes (as I illustrated with a concrete example),
which then invoke the exception-within-exception troll, and it
complicates the system, which has the same effect plus some.
But you propose logging the info at the throw point which would
require collecting the same info thus slowing things down and invoking
the problem-within-problem troll ;-)
To clarify:
Q. Are absolute rules good?
A. No, never!
I don't propose always logging exceptions at the throw point, only, as I
wrote, if you can, and that was in the context of exceptions being
logged anyway. If you're going to log all exceptions anyway, making an
initial log entry at the throw point guarantees that that exception will
be logged. Such a guarantee helps you guard against (1) client code
that doesn't log as it should, (2) crashes, with no (useful) log entry,
and in addition it (3) centralizes things, which is generally good.
There is no difference between logging at the throw point and at the
catch point from this perspective.
KISS - Keep It Simple, Stupid.
How did this pass moderation?
{ Presumably because the poster referred to a well-known software
engineering principle. Alas, the moderators cannot suppress references
to such principles even when the principle's name might be interpreted
as insulting (earlier mentions of the KISS principle don't seem to have
drawn comments in this group or in comp.std.c++, but there is the
possibility that such comments have been made in rejected articles). See
<url: http://en.wikipedia.org/wiki/Kiss_principle>. -mod/aps }
I can only confirm and if possible amplify what Alf-with-mod-hat-on
writes above (of course, only regarding my own intention, not what the
accepting moderator was thinking), that the statement was a direct
reference to the well-known software engineering principle, and I
apologize for not providing the clarifying link & perhaps a smiley then
;-). That said, I'm not an adherent to the political correctness school
of thinking. The Wikipedia article starts out by using a politically
correct new-speak expansion of the acronym, one I've never heard used,
which I think is wrong for an encyclopedia, but refers in turn to
sources that only use the well-known & meaningful expansion I provided.
mostly, except for logging at the point of throw,
Logging at the point of throw needlessly spends CPU/IO and adds noise to
logs even when exception is benign and handled graciously. More importantly
it requires each and every component in your system to be aware of whatever
logging facilities you use. Which doesn't work well with 3rd party libraries
or multi-component projects in general.
Sorry, to me that's not a meaningful statement (no meaning extracted).
Let's try again. How are you going to log? What log facility are you
going to use if you write a library for an unknown client? Do you
intend to require a logging callback? Or write to your own
mylibrary.log file and ruin my nice logging scheme?
Additionally why would you force your logging (necessarily
synchronized and necessarily slow) on my thread running your code
*even if I don't want you to*?
Those are engineering decisions. Obviously the Windows API, say, cannot
be forced to log on your behalf (well, unless you're using a part of the
API that can be configured that way: one should never say never). So
mostly the answer is, "it depends": there's no silver bullet, but hard
trade-off decisions to make.
[snip]
I think you completely missed the point. There is always a logical
call stack that may cross machine boundaries. Code that throws an
exception admits that it doesn't know what to do and asks the code
above it in the logical call stack to decide. The exception may as
well cross the machine boundary (they do in the system I am working on
now). The point I was making is that if you don't know how to handle
some situation as far as the larger system is concerned you have no
business logging it.
It seems you're now dicussing a situation where you want some, but not
all, exceptions logged. In that case you can use a filtering log
facility. The throws will then attempt to log, but whether that results
in actual log entries will then depend on the call context.
The point of logging is to have a trace what happened, no matter what
happens later.
This is tracing, not logging and you cannot realistically do it in a
high performance code or have it always enabled.
Sorry, I used the word "trace" in a general sense, not in the sense of
tracing (all or most of) the program execution.
It may happen, for example, that an exception leads to catastrophic
failure (all the more likely when it's outfitted with a lot of data
baggage).
I don't understand what exactly do you mean by "catastrophic failure"
here.
A catastrophic failure is, for example, depending on the system, an
integer divide by zero, or executing an invalid machine code instruction
resulting from a corrupted stack. Or, as may be likely with a lot of
baggage data in an exception object (as you argued for), a
std::bad_alloc exception during stack unwinding. Generally such
failures prevent after-the-fact logging of the original exception.
At the point of throw it's not known what may happen later.
Hence at that point, the code must act as if anything can happen.
Precisely ;-) Which to me means not do anything other than throw.
What do you trust more to not screw up: arbitrary client code above that
has demonstrably violated your preconditions or resource requirements,
or a true and tested logging facility?
[snip rest]
Cheers,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]