Re: A matter of exception reporting style
* mzdude:
On Aug 12, 9:23 am, "Alf P. Steinbach" <al...@start.no> wrote:
Should derive from std::runtime_error.
Why??
Multiple exclamation marks, ... :-) (I'm sure you can look up that quote)
Anyways, you want to base your exceptions on std::exception in order to support
code that deals with and expects std::exception, and then std::runtime_error is
the logical general choice of standard exception base class.
There's nothing more annoying than using libraries that throw non-standard
exceptions, necessitating exception conversion or big multiple catches in the
calling code.
We don't use narrow char unless forced to for historical
interface reasons.
For exceptions you should.
There is AFAIK no reason to support wide characters in exceptions.
The same internal failure can cause different user level failures; different
internal failures can cause the same user level failure; and the requirements on
information conveyed, internationalization etc. are vastly different.
So user interface messages should ideally not be carried by exceptions.
And so in a non-trivial app it's a good idea to separate exceptions (internal
failure reporting) from the user interface aspect (user failure reporting).
When you do introduce your own exception class it's also a Good Idea to add a
virtual rethrow() routine.
That way exceptions can more easily be propagated across C code, e.g. from
callbacks.
Not sure what you mean by this.
It means that before returning to C code that was called by your code, you can
dynamically copy the exception somewhere (for complete generality it helps if it
supports cloning), and on return from C code you can rethrow the exception with
original type.
For the C code in between may not support exception propagation.
const int ErrCode1 = 1000;
const int Errcode2 = 1001;
...
File1.cpp
void SomeFunct() {
if(cond)
throw Error( ErrCode1, L"This is an error");
}
File2.cpp
void AnotherFunc() {
if(cond)
throw Error( ErrCode1, L"This is an Error.");
}
Note the slight discrepancy in the error strings.
Obviously refactoring is the key to consistency.
But how to refactor?
Introduce a mapping from error codes to strings.
Take care not to make that error code/string the primary message (as it seems to
be above), but just a convenience add-on.
That is the case. The error code is the important. The message is for
the human (maybe).
If you make the error code the important, then you're most probably heading for
the nightmare I mentioned.
At the worst you'll end up with a repository/database of error codes and
strings, a set of small utilities for handling that, a person in charge of that,
and umpteen man-months wasted searching for proper error codes or creating them.
Generally all that matters for code that handles an exception is that there was
an exception, and all that matters for someone inspecting a log is the textual
message and throw context. I use exceptions that can carry a Windows error code.
However, even when an exception is caused by an API failure there isn't
necessarily a reasonable error code available, or the error code can be so
generic as to not say anything really (e.g. E_FAIL), and it doesn't say which
API routine failed, nor which of my routines failed. So the important thing for
debugging, logging and so on is the text, supplied by the throwing code.
Cheers & hth.,
- Alf