Looking for Tips/Writeup on overall approach to Exception Processing

R

Rex

Re: Looking for Tips/Writeup on overall approach to Exception
Processing

Hi All - I am fairly new to C# and am wondering how to best implement
(overall) Exception Processing within my (reasonably-sized) C# Windows
application. I do have a bunch of somewhat random questions on this
and if you can help me with only one or a few, that would still be
APPRECIATED. Here are my questions:

1. Is it recommended to put all of the "Main" coding within a "try"
block (along with a "catch" that catches all Exceptions) so that your
application will never abnormally terminate?

2. As you read the following, realize that I do NOT have a clear
overall approach for this... So much of the following describes some
questions that have initially occurred to me as I consider my design.
So here goes: Let's say most or all of my Application's methods
return a bool to indicate whether the routine successfully completed
or not. The bool will be equal to "false" ONLY if there is a logic
error or system error - never due to some invalid input from the User
and never, for example, because a User file is not found. Does it make
sense to do it this way? And if so, should the calling routine always
check for this "false" value on all called methods??? (which could be
alot of code!) And should the error message that the User sees always
come from the called routine? And does this mean I would implement a
Try block in every called method??? I would very much appreciate
anyone who can help me sort all of this out... which brings me to...

3. Does anyone know of any document on the Web with some tips and/or
suggested overall approaches to Exception Processing?

Thanks!

Rex
 
P

Peter Duniho

1. Is it recommended to put all of the "Main" coding within a "try"
block (along with a "catch" that catches all Exceptions) so that your
application will never abnormally terminate?

I don't know what's recommended. But I wouldn't bother, unless I had some
specific sort of cleanup-before-exit stuff I had to make sure happened, or
if my application had some way to sensibly recover from an exception
*instead* of exiting.

After all, if you have no special cleanup to do, and all you're going to
do is catch the exception and then exit, then that's what Windows does for
you already. :)
2. As you read the following, realize that I do NOT have a clear
overall approach for this... So much of the following describes some
questions that have initially occurred to me as I consider my design.
So here goes: Let's say most or all of my Application's methods
return a bool to indicate whether the routine successfully completed
or not. The bool will be equal to "false" ONLY if there is a logic
error or system error - never due to some invalid input from the User
and never, for example, because a User file is not found. Does it make
sense to do it this way?

I don't think so, not in .NET. I still have methods that return boolean
results, but they do so only in what are considered normal situations. I
would not write a method that returns a boolean, but which should in
theory never return "false" (or "true", depending on how you define the
result :) ). That seems like a waste to me, and is exactly the kind of
situation in which exceptions are useful.

After all, if your method returns a value that should always be "true",
but you require the caller to check the return value, where is the benefit
in that? What is the caller supposed to do with an invalid return value?
Propogate the value back to the caller? Isn't that what exceptions do for
you already?
And if so, should the calling routine always
check for this "false" value on all called methods??? (which could be
alot of code!)

See above. :)
And should the error message that the User sees always
come from the called routine?

Another benefit of exceptions is that they can be specific to what went
wrong. Sometimes it is useful to use the InnerException to wrap an
exception in another exception. This would aid, for example, in having an
exception include both the fact that there was some i/o error, as well as
the fact that the i/o error occurred while trying to perform some
higher-level application operation (the InnerException would be the one
thrown by the file access class, like FileStream for example, while the
wrapping exception would be thrown by the higher-level application code
that was trying to do some operation).
And does this mean I would implement a
Try block in every called method???

You should only implement a try/catch block if you can do something with
the exception. It is pointless to catch an exception only to just rethrow
it. In some cases, you may need to do some cleanup, which would be
another reason to catch the exception, but most of the time any cleanup
you need to do can be handled automatically by the "using" statement with
objects that implement IDisposable.
I would very much appreciate
anyone who can help me sort all of this out... which brings me to...

3. Does anyone know of any document on the Web with some tips and/or
suggested overall approaches to Exception Processing?

Not off-hand, no. But I'm sure they are out there. :)

Pete
 
A

Aneesh Pulukkul[MCSD.Net]

I don't know what's recommended. But I wouldn't bother, unless I had some
specific sort of cleanup-before-exit stuff I had to make sure happened, or
if my application had some way to sensibly recover from an exception
*instead* of exiting.

After all, if you have no special cleanup to do, and all you're going to
do is catch the exception and then exit, then that's what Windows does for
you already. :)


I don't think so, not in .NET. I still have methods that return boolean
results, but they do so only in what are considered normal situations. I
would not write a method that returns a boolean, but which should in
theory never return "false" (or "true", depending on how you define the
result :) ). That seems like a waste to me, and is exactly the kind of
situation in which exceptions are useful.

After all, if your method returns a value that should always be "true",
but you require the caller to check the return value, where is the benefit
in that? What is the caller supposed to do with an invalid return value?
Propogate the value back to the caller? Isn't that what exceptions do for
you already?


See above. :)


Another benefit of exceptions is that they can be specific to what went
wrong. Sometimes it is useful to use the InnerException to wrap an
exception in another exception. This would aid, for example, in having an
exception include both the fact that there was some i/o error, as well as
the fact that the i/o error occurred while trying to perform some
higher-level application operation (the InnerException would be the one
thrown by the file access class, like FileStream for example, while the
wrapping exception would be thrown by the higher-level application code
that was trying to do some operation).


You should only implement a try/catch block if you can do something with
the exception. It is pointless to catch an exception only to just rethrow
it. In some cases, you may need to do some cleanup, which would be
another reason to catch the exception, but most of the time any cleanup
you need to do can be handled automatically by the "using" statement with
objects that implement IDisposable.



Not off-hand, no. But I'm sure they are out there. :)

Pete

Some best practices from MSDN:
http://msdn2.microsoft.com/en-us/library/seyhszts(VS.71).aspx

And some fundementals:http://msdn2.microsoft.com/en-us/library/
2w8f0bss(VS.71).aspx

Again we have many links for best practices posted by developers:
http://www.codeproject.com/dotnet/exceptionbestpractices.asp
http://www.c-sharpcorner.com/Upload...ment11142005020738AM/ExceptionManagement.aspx
 
R

Rex

Hi Peter and Aneesh,
Thank you both your input - they were both helpful in their own way!
Peter, a couple of points: 1. The advantage of putting a universal
"try/catch" statement in the Main method is that the User does not get
the awful-looking message which asks the User if they wish to SEND the
error to Microsoft. It might be the very same message but it doesn't
look as bad. 2. I've been thinking of this issue for the last 24
hours, and I think I have an interesting solution, as least as
something to try: I'm going to create a static (global) variable (a
string array probably) and call it something like CurrMethodName. Then
at the top of most or every method, I'm going to set its value to the
name of the current method. Then I'll do the Main-level universal
Try/Catch, and display both the error message AND the value in the
string (for diagnostic purposes). If you or anyone has further
thoughts on this, I am open! Thanks again,
Rex
 
F

Fred Mellender

Consult documentation on Exception.StackTrace property. You
could print this out (instead of capturing the name of the method upon entry
to each function).
 
P

Peter Duniho

Peter, a couple of points: 1. The advantage of putting a universal
"try/catch" statement in the Main method is that the User does not get
the awful-looking message which asks the User if they wish to SEND the
error to Microsoft. It might be the very same message but it doesn't
look as bad.

Well, I guess that's a matter of opinion. If you are embarassed that a
user might see the standard Windows application error dialog, and don't
want information sent to Microsoft that might help avoid similar problems
in the future, I guess you can wrap an exception in your own dialog. You
could even design the dialog to make it look like someone else's fault if
you like.

But personally, I don't see the difference. The application shouldn't
have an unhandled exception in the first place, and changing the visual
representation of the unhandled exception doesn't seem useful to me.

Your mileage may vary.
2. I've been thinking of this issue for the last 24
hours, and I think I have an interesting solution, as least as
something to try: I'm going to create a static (global) variable (a
string array probably) and call it something like CurrMethodName. Then
at the top of most or every method, I'm going to set its value to the
name of the current method. Then I'll do the Main-level universal
Try/Catch, and display both the error message AND the value in the
string (for diagnostic purposes).

It seems to me that there are better ways to deal with that than having to
go modify each and every method in your application to set a "global"
variable. For example, the Exception class already includes a StackTrace
member that should give you all the information you need to indicate where
the exception occurred. However, if that's how you prefer to address the
issue, I can't think of a good reason to not do it that way.

Pete
 
R

Rex

Fred and Pete - Thanks alot!! I did not know about that property. You
may have saved me a bunch of code. I'll look into it, and thanks
again,
Rex
 
T

Tim Rowe

Rex said:
Re: Looking for Tips/Writeup on overall approach to Exception
Processing

I think it would be useful for you to have a look at "Design By Contract".
Although I have reservations about it as a design approach, the concept of
contracts on which it is built is a good way of thinking about how to use
exceptions.
So here goes: Let's say most or all of my Application's methods
return a bool to indicate whether the routine successfully completed
or not. The bool will be equal to "false" ONLY if there is a logic
error or system error - never due to some invalid input from the User
and never, for example, because a User file is not found. Does it make
sense to do it this way?

Probably not. Think about what the method should do, and what conditions
have to apply for it to succeed in doing that. Document those conditions
(the "preconditions")and require the client to make sure they apply, at
least insofar as the client can. For debugging check that the client /has/
met the preconditions and throw an exception if they haven't. If it's an
exposed interface (eg, a library interface) consider leaving the check in
the the released version. Debugging or not, if the preconditions are met and
the method fails to do what it promises, raise an exception.

That's not the be-all and end-all of exception handling, but it's a good
start.
And if so, should the calling routine always
check for this "false" value on all called methods??? (which could be
alot of code!)

Which is one big advantage of exceptions.
And should the error message that the User sees always
come from the called routine?

Another big advantage of exceptions is that they can be handled at an
appropriate level. A low level method might have no idea about what it's
being used for, and so has no change of producing a message that's
meaningful to the user in the context of what they were trying to do. Let
the exception propogate up to a higher level, and the application can
account for what it was trying to achieve with the lower level call, and
what it means to the user. Then you can give an error message in the
/user's/ terms, not in the /program's/ terms (if the error looks like being
a logic error, though, consider making the exception trace available to the
user in a form that they can easily report back to you, such as an error log
file that they can email to you).

Any error message that a low-level method can generate is almost certainly
useless to a user, and will probably only serve to annoy them.
And does this mean I would implement a
Try block in every called method??? I would very much appreciate
anyone who can help me sort all of this out... which brings me to...

No. You only catch an exception if you are in a position to do something
useful with it.
3. Does anyone know of any document on the Web with some tips and/or
suggested overall approaches to Exception Processing?

This thread? ;-)
 
T

Tim Rowe

2. I've been thinking of this issue for the last 24
hours, and I think I have an interesting solution, as least as
something to try: I'm going to create a static (global) variable (a
string array probably) and call it something like CurrMethodName. Then
at the top of most or every method, I'm going to set its value to the
name of the current method. Then I'll do the Main-level universal
Try/Catch, and display both the error message AND the value in the
string (for diagnostic purposes). If you or anyone has further
thoughts on this, I am open! Thanks again,

A maintenance nightmare, and a waste of time. C# already knows where the
exception was generated. Anyway, you should handle the exception at the
first point at which you have enough information to usefully handle it. In
an event-driven architecture that is unlikely to be the "main" level, and if
you let an exception propogate to that level you've almost certainly got
your design badly wrong.
 
M

Michael A. Covington

The application shouldn't have an unhandled exception in the first place
That's the salient point here...

Truly weird things ("this disk drive disappeared while I was writing on it")
will occasionally happen and can't or shouldn't be foreseen. There's a
place for unhandled exceptions, but they should be for strange events.
 
P

Peter Duniho

Truly weird things ("this disk drive disappeared while I was writing on
it")
will occasionally happen and can't or shouldn't be foreseen.

An application should not exit because of a file i/o error.

If the boot drive disappears, then yes...there are certain things outside
an application's control. But if the boot drive disappears, the
application's failure to write to a file and subsequent exit is the least
of the user's worries (though even in that case, the exception caused by
the act of writing to the file should still be handled). And for storage
devices _generally_ disappearing or otherwise having an error, that
absolutely CAN be foreseen and should be addressed.
There's a
place for unhandled exceptions, but they should be for strange events.

By definition, an unhandled exception is one that the application didn't
handle. The application should always protect itself against exceptions
by handling them.

Pete
 
M

Michael A. Covington

Peter Duniho said:
An application should not exit because of a file i/o error.

I agree. The application should cancel the file i/o operation and return
control to the user, if possible, or if not, at least report intelligently
what happened. I need to think of something weirder for an example.
 
B

Ben Voigt [C++ MVP]

Michael A. Covington said:
I agree. The application should cancel the file i/o operation and return
control to the user, if possible, or if not, at least report intelligently
what happened. I need to think of something weirder for an example.

Some things are going to kill your app no matter how defensively you code.

RAM corruption, for example. If your recovery code gets corrupted, you're
totally out of luck.
 

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

Similar Threads


Top