Throwing exception in a try block?

K

Kevin Yu

is it a bad programming design to throw exception in the try block then
catch it??
 
M

Miha Markic [MVP C#]

Hi Kevin,

Depends. For example, if you have a deeply nested procedure, throwing an
exception to exit might be a viable way.
However, normally throwing an exception is costly plus throwing an exception
should signal an error.
 
H

Helge Jensen

Kevin said:
is it a bad programming design to throw exception in the try block then
catch it??

Here are some guidelines that i have formulated after having tried
different strategies of exceptions:

Don't use exceptions to indicate errors you expect to occur.

Don't throw exceptions to "break" the program flow to a specific
catch-handler (goto):

try {
...
if ( unexpectedSituation )
throw new UnexpectedSituation();
...
} catch ( UnexpectedSituation ) {
// this is a complicated way to do goto
}

But if an unhandled exceptional situation occurs, then do what you would
normally do, for eample:

Stream s = new Stream("x");
try {
byte[] data = new byte[4];
int read = 0;
while ( read < data.Length ) {
int r = s.Read(data, read, data.Length - read);
if ( r == 0 )
throw new ParseError("Stream ended before data could be read");
}
return data;
} catch ( InvalidOperationError ) { // unrelated to ParseError
// Reading failed!
} finally {
s.Close();
}

NOTE: you could use: "using (Stream s = new Stream("x")) { ... }"
instead of try/catch.

It is often good to write the code to have minimal try/catch-blocks, for
example if there is a risk that dict[key] may not be a Foo:

Foo foo = (Foo)dict[key];
try {
foo.f(...);
} catch ( FooProcessingException ) {
... // sensible error handler
}

instead of:

try {
((Foo)dict[key]).f(...);
} catch ( FooProcessingException ) {
... // sensible error handler
}

So that error-handling is narrowly applied to the code that is expected
to expose the error.

In general: only catch if you can actually do anyting to remedy the
error, or is at the top of the call-stack. A possible exception is
catching for logging and retrow:

try {
f(...);
catch ( Exception e ) {
Log(e);
throw;
}
 
J

John Vottero

Kevin Yu said:
is it a bad programming design to throw exception in the try block then
catch it??

It depends on what you're doing and why you're doing it. If you're catching
exceptions so that you can do some sort of rollback or cleanup and then
throw (or rethrow) an exception then it could be a fine design. If you're
throwing and catching as a neat-o way of passing data then, it's a bad
design.

What are you doing?
 
M

Mohammad

Helge,

If you don't mind, I would like to add that, from my own experience, I
have yet to come across a case where anything can be done to remedy an
error flagged by an excpetion. The only case that comes to mind where
that is actually doable is in the case of parsing strings to other data
types, in which case the error can be corrected by setting the target
variable to some sensible default.

So, again from my own experience, the best thing to do in the case of
an exception is to simply roll back any changes done within the scope
of the operation and letting the excpetion bubble up to the caller.

This can be accomplished without writing any exception handling code by
borrowing the Resource Initlializing is Acquisition (RIIA) idiom from
C++, which is somewhat easy to implement in C# 2.0, as can be seen from
this article: http://www.codeproject.com/csharp/exceptions_generics.asp

I would also like to add that I don't believe that catching exceptions
just to wrap them in custom exceptions and them rethrow them is a good
idea. Same for logging excpetions, which should be done in one place
and one place only for the whole program.
 
K

Kevin Yu

I have posted another thead earlier on the code I am reading, I can see it's
clearly the guy is from a C++ backgroup, he basically try and catching
everything including the integer assignment, so I think he's abusing the try
catch statement, but I can't report to the police. so I asked the question
on the newsgroup, I got different opinions of the try catch block, I mean if
there is an exception, yea, for sure I want to catch it, but if wrapping
everything in the try catch block is the way to go?

I mean how much confidence you need for .NET?

any inside??


Kevin



Miha Markic said:
Hi Kevin,

Depends. For example, if you have a deeply nested procedure, throwing an
exception to exit might be a viable way.
However, normally throwing an exception is costly plus throwing an exception
should signal an error.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
www.rthand.com
SLODUG - Slovene Developer Users Group www.codezone-si.info

Kevin Yu said:
is it a bad programming design to throw exception in the try block then
catch it??
 
K

Kevin Yu

Helge
he did the exactly same thing on all the code, I guess that's his fabulous
design.
try {
...
if ( unexpectedSituation )
throw new UnexpectedSituation();
...
} catch ( UnexpectedSituation ) {
// this is a complicated way to do goto
}

Helge Jensen said:
Kevin said:
is it a bad programming design to throw exception in the try block then
catch it??

Here are some guidelines that i have formulated after having tried
different strategies of exceptions:

Don't use exceptions to indicate errors you expect to occur.

Don't throw exceptions to "break" the program flow to a specific
catch-handler (goto):

try {
...
if ( unexpectedSituation )
throw new UnexpectedSituation();
...
} catch ( UnexpectedSituation ) {
// this is a complicated way to do goto
}

But if an unhandled exceptional situation occurs, then do what you would
normally do, for eample:

Stream s = new Stream("x");
try {
byte[] data = new byte[4];
int read = 0;
while ( read < data.Length ) {
int r = s.Read(data, read, data.Length - read);
if ( r == 0 )
throw new ParseError("Stream ended before data could be read");
}
return data;
} catch ( InvalidOperationError ) { // unrelated to ParseError
// Reading failed!
} finally {
s.Close();
}

NOTE: you could use: "using (Stream s = new Stream("x")) { ... }"
instead of try/catch.

It is often good to write the code to have minimal try/catch-blocks, for
example if there is a risk that dict[key] may not be a Foo:

Foo foo = (Foo)dict[key];
try {
foo.f(...);
} catch ( FooProcessingException ) {
... // sensible error handler
}

instead of:

try {
((Foo)dict[key]).f(...);
} catch ( FooProcessingException ) {
... // sensible error handler
}

So that error-handling is narrowly applied to the code that is expected
to expose the error.

In general: only catch if you can actually do anyting to remedy the
error, or is at the top of the call-stack. A possible exception is
catching for logging and retrow:

try {
f(...);
catch ( Exception e ) {
Log(e);
throw;
}

--
Helge Jensen
mailto:[email protected]
sip:[email protected]
-=> Sebastian cover-music: http://ungdomshus.nu <=-
 
K

Kevin Yu

John

don't get me wrong, I just want some justice on someone else's code that I
need to follow and support.

basically he wrap everything in try catch block even when instantiating a
new object, he will check for if the newly created object is null, then
throw and exception, I mean if the new operate fail to instantiate an
instance aka it's out of memory, the runtime will throw and
OutofMemoryException, the guys is clearly came from a C++ background.
anyway, is it a good idea to wrap everything inside a try catch block, I
read somewhere that try block doesn't cost anything, only when exception
occur, it will cost u, so does that mean it's a good idea to wrap everything
in try catch, I mean hack, this will make the system *Robus*.

enlighten me.

Kevin
 
J

Jeff Louie

My opinion is that this can be used sparingly when it makes the code
flow
easier to read. So if I have a catch that basically returns false on an
error, sets
an error message etc. and I have a invariant error that should also
return
false, then it is very simple to throw an exception on an invariant
error and
just reuse the code block in the catch. In other words, I think
throwing an
exception in the try block is acceptable when it makes the code easier
to read
and follow and understand what is going on. Else I don't throw
exceptions in
try.

Regards,
Jeff
is it a bad programming design to throw exception in the try block then
catch it??
 
K

Kevin Yu

Miha,

good to hear from you again, I think you help me out couple of years ago on
the dataset stuff, nice to see you are active in this newsgroup.


Kevin



Miha Markic said:
Hi Kevin,

Depends. For example, if you have a deeply nested procedure, throwing an
exception to exit might be a viable way.
However, normally throwing an exception is costly plus throwing an
exception should signal an error.

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
www.rthand.com
SLODUG - Slovene Developer Users Group www.codezone-si.info

Kevin Yu said:
is it a bad programming design to throw exception in the try block then
catch it??
 
K

Kevin Yu

Jeff Louie said:
My opinion is that this can be used sparingly when it makes the code
flow
easier to read. So if I have a catch that basically returns false on an
error, sets
an error message etc. and I have a invariant error that should also
return
false, then it is very simple to throw an exception on an invariant
error and
just reuse the code block in the catch. In other words, I think
throwing an
exception in the try block is acceptable when it makes the code easier
to read
and follow and understand what is going on. Else I don't throw
exceptions in
try.

throwing an exception in the try block is costly, it slows down the prog,
yea, it make the code easier to read,
I think with a better refactory technique such design can be avoided. in my
case ( the code I am reading) it's messy
because even in the catch block, and try catch block is also there in case
of the exception occur in the catch block from
writing the error to eh event log. I mean how many level of exception
handling u need.

making the program easier to read doesn't mean you can throw exceptions
freely, for example, in the main function, there is a
try can catch block, then in the try catch, there are bunch of high level
function calls, within those functions, a try catch block
is used to handle any exception that might occur, but then after handling
the exception, e.g write error event log or email people
the function will throw the exception/bubble it up to the main function, in
stead of doing that, why doesn't it just return a bool
then base on the boolean an if statement can direct the program flow instead
of getting to the exception handler that way, sometimes
there is a finally block to clean up stuff, if and object didn't even get
instantiated or started because of the proceeding exception, then no need to
do the
clean up for those object, I mean sure you can use if statement to check if
not null or something before cleaning up or aborting a thread, then
where is the efficiency?
 
J

Jon Skeet [C# MVP]

Kevin Yu said:
throwing an exception in the try block is costly, it slows down the
prog, yea, it make the code easier to read, I think with a better
refactory technique such design can be avoided. in my case ( the code
I am reading) it's messy because even in the catch block, and try
catch block is also there in case of the exception occur in the catch
block from writing the error to eh event log. I mean how many level
of exception handling u need.

Throwing an exception is *slightly* costly - but not very expensive
really. You don't want to start doing it in a short loop, for instance,
but exceptions aren't nearly as expensive as a lot of people seem to
think. In the very rare cases where it makes the code significantly
more readable, I'd hold that as more important than performance until
it was proven that that bit of code was an application bottleneck and
that the exceptions were the problem.

As an example of how overblown the issue of the performance penalty for
exceptions is, on another group a while ago someone was asking whether
or not his application was suffering because it was throwing a couple
of hundred exceptions per *hour*. Many people said that yes, this was
probably slowing his application down significantly. My laptop can
throw a hundred thousand exceptions per *second* - in other words, his
200 exceptions would take less than a millionth of the hour in which
they were thrown.
 
H

Helge Jensen

Mohammad said:
Helge,

If you don't mind, I would like to add that, from my own experience, I
have yet to come across a case where anything can be done to remedy an
error flagged by an excpetion.

Retrying an operation, for example:

- When a protocol over an unreliable media comes out of sync.
- When a modem dial-up fails
- When a user can be asked to enter another possibility
that is actually doable is in the case of parsing strings to other data
types, in which case the error can be corrected by setting the target
variable to some sensible default.

Which is a kind of "else-if-by-error".

This kind of "recovery-by-default" is usually not a good idea (atleast
in the long run) since it removes the possibility of the caller noticing
that the default was chosen instead of the selected value (which was
misspelled and thus gave a parse-error).
So, again from my own experience, the best thing to do in the case of
an exception is to simply roll back any changes done within the scope
of the operation and letting the excpetion bubble up to the caller.

I couldn't agree more :)

If you are at the top of the callstack you *do* get a special
obligation, to log or whatnot, since the exception would otherwise pass
out of history.
This can be accomplished without writing any exception handling code by
borrowing the Resource Initlializing is Acquisition (RIIA) idiom from
C++, which is somewhat easy to implement in C# 2.0, as can be seen from
this article: http://www.codeproject.com/csharp/exceptions_generics.asp

"finally" is also nice, when the cleanup code isn't reusable.

RIIA is a great idiom, and fits *so* nicely into the C# using-syntax.
You can (relatively) easily move repeated cleanup from "finally"-clauses
to RIAA/using:

class SuspendUpdate: IDisposable {
readonly Control control;
public SuspendUpdate(Control control) {
this.control = control;
control.SuspendLayout();
}
public void Dispose() { control.ResumeLayOut(); }
public ~SuspendUpdate() {
throw new InvalidProgram(
string.Format("Forgot to Dispose {0}", this.GetType().FullName));
}
}
I would also like to add that I don't believe that catching exceptions
just to wrap them in custom exceptions and them rethrow them is a good

My opinion exactly. wrapping is evil, for one thing it destroys the
possibility to "catch-by-type".

The only catch/rethrow I do is when (usually due to rather poor design)
a subcomponent has to iterate through several operations:

IDictionary exceptions = new Hashtable();
foreach ( Foo foo in container )
try {
foo.f();
} catch ( Exception e) {
exceptions.Add(foo, e);
}
}
if ( exceptions.GetEnumerator().MoveNext() )
throw new SomeOperationsFailed(exceptions);

I prefer doing a callback in this situation, but somethimes the
interface is locked down due to years of use by customers.
idea. Same for logging excpetions, which should be done in one place
and one place only for the whole program.

Well,... yes -- but sometimes components wish to keep separate logs of
unexpected errors, for example to prove that it's the caller that's
doing things wrong. That's when:

try {
f();
} catch ( Exception e ) {
Log(e);
throw; // notice: rethrow!
}

comes in handy.
 
H

Helge Jensen

Kevin said:
basically he wrap everything in try catch block even when instantiating a
new object, he will check for if the newly created object is null, then
throw and exception, I mean if the new operate fail to instantiate an
instance aka it's out of memory, the runtime will throw and
OutofMemoryException, the guys is clearly came from a C++ background.

None of these things are good behaviour in C++ either :)

BTW: The default operator new should throw on out-of-memory errors, you
need to use "new(nothrow) Foo(...)" to get a null-pointer.
anyway, is it a good idea to wrap everything inside a try catch block, I
read somewhere that try block doesn't cost anything, only when exception
occur, it will cost u, so does that mean it's a good idea to wrap everything
in try catch, I mean hack, this will make the system *Robus*.

Getting a bit on the sarcastic side, aren't you :)
enlighten me.

C++ doesn't have finally, so unless you RIAA you get:

Transaction t = Transaction(...);
try {
t.foo();
} catch ( ... ) {
t.Rollback();
throw;
}
t.Commit();

Which is ok in my book. (I would prefer RIAA on Transaction, but if it's
only in a few places...)
 
M

Miha Markic [MVP C#]

As an example of how overblown the issue of the performance penalty for
exceptions is, on another group a while ago someone was asking whether
or not his application was suffering because it was throwing a couple
of hundred exceptions per *hour*. Many people said that yes, this was
probably slowing his application down significantly.

Hehe :)
 
K

Kevin Yu

hi All

After all these discussions, I only have couple of questions here.

1. is it a good idea to wrap everything in try catch block? explain in
evidence/examples please.

2. is throwing exception in a try catch block a good idea? can Goto be an
alternative??

3. is rethrowing an exception a good design pattern or necessary? I mean
instead of returning a boolean

Kevin
 
J

John Vottero

Kevin Yu said:
John

don't get me wrong, I just want some justice on someone else's code that I
need to follow and support.

basically he wrap everything in try catch block even when instantiating a
new object, he will check for if the newly created object is null, then
throw and exception, I mean if the new operate fail to instantiate an
instance aka it's out of memory, the runtime will throw and
OutofMemoryException, the guys is clearly came from a C++ background.
anyway, is it a good idea to wrap everything inside a try catch block, I

No, it is not a good idea to wrap everything in a try/catch block. Don't
use try/catch unless you have a real reason to catch an exception or cleanup
(finally). What does the catch do? If it just rethrows the exception, then
you're wasting your effort, making your code hard to read and not adding any
value.

You might remind this guy that he can still check things and throw
exceptions without wrapping the code in a try/catch.
read somewhere that try block doesn't cost anything, only when exception
occur, it will cost u, so does that mean it's a good idea to wrap
everything

That is true, try/catch is almost free until an exception is thrown.
 
J

John Vottero

Kevin Yu said:
hi All

After all these discussions, I only have couple of questions here.

1. is it a good idea to wrap everything in try catch block? explain in
evidence/examples please.

Yes and no. It's a very good idea to have a try/catch at the very top of
your program so that you can properly record exceptions. You actually get
this without writing any code, if an exception bubbles all they way up the
last chance exception handler shows you the call stack and exception and the
program exits. If that's acceptable, you don't have to do anything. If you
want to do something else, like write the exception to a log, use a single
try/catch at the top of your program.

After that, don't add a try/catch/finally unless you have a reason to.
2. is throwing exception in a try catch block a good idea? can Goto be an
alternative??

Yes, if you have an exception the best way to report it is to throw an
exception. I don't see how goto would be useful for reporting an
exceptional condition.
3. is rethrowing an exception a good design pattern or necessary? I mean
instead of returning a boolean

There's no one right answer. First, don't catch the exception unless you
have a reason. If you're just rethrowing it, then it's a waste. There are
plenty of cases where you can catch an exception and return true or false
but those would be expected exceptions (FormatExceptions etc). In general,
you want to rethrow the exception because it contains a lot of information
that will help you solve the problem. You don't want to get into a
situation where all of your methods return true or false to indicate an
error and you call GetLastException to find out what the error was.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top