By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,190 Members | 772 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,190 IT Pros & Developers. It's quick & easy.

Nested exceptions (ala Java)

P: n/a
Consider the following operation:

class C
{
public:
...
virtual void override_me() = 0;

struct AnException : public std::runtime_error {
AnException(const std::string& arg)
: std::runtime_error(arg)
{}
};

void run_some_operation()
{
try {
...
this->override_me();
...
} catch(const std::exception& e) {
throw AnException(e.what()
+ " raised from 'override_me()' "
+ " in 'run_some_operation()'");
}
}

void run_another_operation()
{
try {
...
this->override_me();
...
} catch(const std::exception& e) {
throw AnException(e.what()
+ " raised from 'override_me()' "
+ " in 'run_another_operation()'");
}
}

...
}; // class C
Now, I was doing some Java a few months ago, and I encountered Java's way of
doing this. Each 'Throwable' has another member, a 'Cause'. So above, the
'Cause' of the 'AnException' would be whatever exception 'override_me()' threw.

In Java, of course, you can get a stack trace to the point where the exception
was thrown, so storing a nested exception allows the nested exception's
stacktrae to also be shown. In the above example, the stacktrace for the
'AnException' would be where it is thrown in the 'run_some_operation()'
function, while the stack trace for the exception that triggered that
exception be from wherever it was thrown. (I hope that's not too confusing.)

Now, in C++ exceptions store stack traces up to the point they were thrown
from (it would be nice if they could...) so nesting exceptions like this isn't
too useful. But it still allows a little bit more detail to be stored, and
avoids having to do some text processing (appending the message of one
exception as well as its name to the message of the other one).

I'm thinking of creating a new base class that all my exceptions derive from
that allows this behaviour. Do you guys think it'd be a useful feature to
immitate? Is there anything I'm not thinking of? (I know I'd need to store a
copy of the exception thrown, which I can't do for standard exceptions. But
my own exceptions will all have a 'virtual copy constructor' that I'll use to
get a duplicate of them to store, so that'll be no problem.)

Thanks, please be gentle with the flames if I'm talking cobblers :-)

--
To reply, take of all ZIGs !!
Feb 20 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
TB
Asfand Yar Qazi skrev:
Consider the following operation:

class C
{
public:
...
virtual void override_me() = 0;

struct AnException : public std::runtime_error {
AnException(const std::string& arg)
: std::runtime_error(arg)
{}
};

void run_some_operation()
{
try {
...
this->override_me();
...
} catch(const std::exception& e) {
throw AnException(e.what()
+ " raised from 'override_me()' "
+ " in 'run_some_operation()'");
}
}


C++ is not Java. The statement

e.what() + "..." + "...";

does not do what you think it does.

--
TB @ SWEDEN
Feb 20 '06 #2

P: n/a
TB wrote:
Asfand Yar Qazi skrev:
Consider the following operation:

class C
{
public:
...
virtual void override_me() = 0;

struct AnException : public std::runtime_error {
AnException(const std::string& arg)
: std::runtime_error(arg)
{}
};

void run_some_operation()
{
try {
...
this->override_me();
...
} catch(const std::exception& e) {
throw AnException(e.what()
+ " raised from 'override_me()' "
+ " in 'run_some_operation()'");
}
}

C++ is not Java. The statement

e.what() + "..." + "...";

does not do what you think it does.


Yeah, I cobbled the above code together in a few minutes. I know I have do do
a "std::string(e.what()) + ...;

I'm a C++ programmer first, then a Java one if at all! :-)

--
To reply, take of all ZIGs !!
Feb 20 '06 #3

P: n/a
* Asfand Yar Qazi:

[idea of tacking on information to exception passing trough function]


You're not the first to think of that. We've all done it... ;-) With
macros and the whole shebang -- consider where the pressure to add
__func__ and so on comes from (it's the automated info-gathering).

Exception information is useful for mainly two purposes: debugging, and
logging.

Intercepting and rethrowing exceptions helps logging and "manual"
debugging, but interfere with interactive and JIT debuggers such as
those common in Windows programming (in particular, if you step over a
call and an exception occurs, you'd like the debugger to go right to
where that exception originated, not the latest rethrower, which is a
strong low-level-trenches argument for using RAII instead of try-catch).
Also, on the negative side, adding info makes exceptions less
efficient, and it can be very dangerous for that overly dangerous
exception std::bad_alloc. Although, of course, one may argue that the
only reasonable handling of std::bad_alloc is to install a new-handler
that logs the incident, says goodbye, and calls std::exit or std::abort.

--
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?
Feb 20 '06 #4

P: n/a
Alf P. Steinbach wrote:
* Asfand Yar Qazi:
>
> [idea of tacking on information to exception passing trough function]
You're not the first to think of that. We've all done it... ;-) With
macros and the whole shebang -- consider where the pressure to add
__func__ and so on comes from (it's the automated info-gathering).


lol. Actually, I was trying to get some input into whether or not Java's way
of 'nesting' exceptions as 'causes' was feasible.

Exception information is useful for mainly two purposes: debugging, and
logging.

Intercepting and rethrowing exceptions helps logging and "manual"
debugging, but interfere with interactive and JIT debuggers such as
those common in Windows programming (in particular, if you step over a
call and an exception occurs, you'd like the debugger to go right to
where that exception originated, not the latest rethrower, which is a
strong low-level-trenches argument for using RAII instead of try-catch).
Also, on the negative side, adding info makes exceptions less
efficient, and it can be very dangerous for that overly dangerous
exception std::bad_alloc. Although, of course, one may argue that the
only reasonable handling of std::bad_alloc is to install a new-handler
that logs the incident, says goodbye, and calls std::exit or std::abort.


Thanks - I will implement my own Exception base class (in fact, I already
have...) I wish there was a way to generate stack traces like in Java with
exceptions - out-side of the debugger of course.

I seem to remember in GCC you have to set a breakpoint to the function
_Unwind_RaiseException and you'd then be able to get a backtrace of where the
exception was about to be thrown.) Wish there was some way of getting
information like this in a standard manner.

--
To reply, take of all ZIGs !!
Feb 21 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.