Exception handling suggestions

Z

Zytan

Ok something simple like int.Parse(string) can throw these exceptions:
ArgumentNullException, FormatException, OverflowException

I don't want my program to just crash on an exception, so I must
handle all of them. I don't care about which one happened, except to
write out exception.Message to a log file. It seems verbose to write
out three handlers that all do the same thing. So, I could just catch
Exception. But, is that recommended? It'll catch everything, even
out of memory exceptions.

What do you suggest?

Zytan
 
V

VJ

main
{
AppDomain.CurrentDomain.UnhandledException+=new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new MyFirstForm());
}

private static void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
{
// The app shuts down.., you can log here..


//After log exit
Application.Exit();

}

That should take care of it..
VJ
 
Z

Zytan

main
{
AppDomain.CurrentDomain.UnhandledException+=new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new MyFirstForm());
}

private static void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
{
// The app shuts down.., you can log here..
//After log exit
Application.Exit();
}

Wow, thanks, VJ. Ok, so what is Application? Is that a name you
made? I am testing this in a console app, and it doesn't exist.

Also, I can't actually test this code, since the debugger always halts
the program on an unhandled exception. How do you test this?

Actually, I was thinking about how do I handle exceptions in which I
don't want the program to quit? For example, for int.Parse(), I just
want to catch everything, and keep the program running, since the data
passed into Parse() could possible be improper, so I want to catch it,
and notify me, but continue running. Is catching Exception really a
good idea?

Zytan
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Zytan said:
Ok something simple like int.Parse(string) can throw these exceptions:
ArgumentNullException, FormatException, OverflowException

I don't want my program to just crash on an exception, so I must
handle all of them. I don't care about which one happened, except to
write out exception.Message to a log file. It seems verbose to write
out three handlers that all do the same thing. So, I could just catch
Exception. But, is that recommended? It'll catch everything, even
out of memory exceptions.

What do you suggest?

Zytan

If the string really can be null, that is easy to check for. You should
check that before calling the method instead of waiting for the exception.

If you don't really need to determine the exact reason why the string
can't be converted, you can use the int.TryParse method instead. Then
you will not need any exception handling at all.
 
Z

Zytan

If the string really can be null, that is easy to check for. You should
check that before calling the method instead of waiting for the exception.

Actually, I just do:
int result = int.Parse("0" + s);
so, nulls are handled already.

I'm concerned with s == "ABC". The data that s can be may be warped
sometimes, and this is actually a decent spot to check to ensure it is
not warped.
If you don't really need to determine the exact reason why the string
can't be converted, you can use the int.TryParse method instead. Then
you will not need any exception handling at all.

Ah, ok, thanks, Göran!

Zytan
 
V

VJ

yes as Goran says its better to safe, than sorry.. but again what I gave is
unexpected situations at a global level.. That is provided by the .NET
environment, for windows applications. Also as note... each try/catch block
is expensive so try to minimze them, and check your parameters before you
execute.

For a console app.. not sure if there one such, my expertise is limited
there..sorry i cant help much.

VJ

Zytan said:
If the string really can be null, that is easy to check for. You should
check that before calling the method instead of waiting for the exception.

Actually, I just do:
int result = int.Parse("0" + s);
so, nulls are handled already.

I'm concerned with s == "ABC". The data that s can be may be warped
sometimes, and this is actually a decent spot to check to ensure it is
not warped.
If you don't really need to determine the exact reason why the string
can't be converted, you can use the int.TryParse method instead. Then
you will not need any exception handling at all.

Ah, ok, thanks, Göran!

Zytan
 
Z

Zytan

yes as Goran says its better to safe, than sorry..

I agree, and thus my post. I don't want to just handle
FormatException, when int.Parse can throw 3 different exceptions.
But, int.TryParse is perfect!
but again what I gave is
unexpected situations at a global level..

Right. What I want to know is how do I handle the exceptions that may
possibly be thrown from each function that has a change of throwing.
Like, for my int.Parse, the data could be garbled, so ALL exceptions
COULD happen. For other functions, network problems could throw
exceptions. I need to therefore test them all. And I've heard
cacthing Exception is bad, since because it gets them all, it gets out
of memory exceptions, as well, which is no good.

But, your solution is the solution to what to do with those out of
memory exceptions that are not caught (since we don't catch
Exception), and then the log can be written, error report sent home,
and gracefully exit.
Also as note... each try/catch block
is expensive so try to minimze them, and check your parameters before you
execute.

Yes, thanks. In the int.Parse case, it could be anything. So,
int.TryParse is what is needed to do the check. And no exception!
For a console app.. not sure if there one such, my expertise is limited
there..sorry i cant help much.

Well, ok, I am making a windows app, but i test in console. So, your
code compiles as-is in a windows app? I will try it.

Zytan
 
Z

Zytan

main
{
AppDomain.CurrentDomain.UnhandledException+=new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.Run(new MyFirstForm());
}

Ok, if this is for a windows app, what is "main"? The main form's
constructor? After InitializeComponent? No it can't be, because you
are running the first form from this. Ah, it's in Program.cs! So, I
have to change this file, and add that event handler addition line, I
see.

Ok, Application.Run(new MyFirstForm()) does work here! It doesn't in
a console app. It is really System.Windows.Forms.Application. I see.
private static void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs e)
{
// The app shuts down.., you can log here..

//After log exit
Application.Exit();
}

I presume this code must also go in Program.cs?

It works! The code is run before the debugger tells me the exception
is unhandled! So, i can test it! Thanks, VJ!

Zytan
 
B

Bruce Wood

Ok, if this is for a windows app, what is "main"? The main form's
constructor? After InitializeComponent? No it can't be, because you
are running the first form from this. Ah, it's in Program.cs! So, I
have to change this file, and add that event handler addition line, I
see.

You can add the event handler anywhere, but it's best to do it as
early as possible so that the minimum amount of code runs before the
handler is hooked up.

There is also the Application.ThreadException event. I always handle
them both.

http://msdn.microsoft.com/library/d...formsapplicationclassthreadexceptiontopic.asp

Main, by the way, is the main entry point into any application,
console or WinForms. It is usually the first piece of your code that
the CLR calls, and it's usually where you set up global exception
handlers.
Ok, Application.Run(new MyFirstForm()) does work here! It doesn't in
a console app. It is really System.Windows.Forms.Application. I see.



I presume this code must also go in Program.cs?

Well, not necessarily. For example, I have mine in a standard error
logging class, and from my Main I call something like:

ErrorLog.Instance.SetupConsoleErrorHandling();

and inside there I subscribe to the events and the ErrorLog class
contains the event handler methods. Nonetheless, that's just because I
wanted a reusable utility. You can also have the method in your main
program .cs file. Nothing wrong with that.


Finally, I would like to offer some general advice on catching
exceptions: catch only what you can handle. Or, put another way, don't
catch an exception unless you can take some substantial action
regarding it. There are other threads in this newsgroup on exception
handling... when and how to catch an exception, but I wanted to point
that out because it explains why you (almost) never catch (Exception
ex): because it's very rare that you can take some intelligent action
with any exception that could possible happen.

The exception to that rule, of course, being logging, and that's what
global exception handlers are for.
 
Z

Zytan

You can add the event handler anywhere, but it's best to do it as
early as possible so that the minimum amount of code runs before the
handler is hooked up.

Yes, so that it's set up to handle an exception even from the
initialization code you have.
There is also the Application.ThreadException event. I always handle
them both.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpre...

Ok, I'll look into that. What are ThreadExceptions? Like when a GUI
control is attempted to be accessed by another thread?
Main, by the way, is the main entry point into any application,
console or WinForms. It is usually the first piece of your code that
the CLR calls, and it's usually where you set up global exception
handlers.

Right, I should have known that, but I didn't know where it was hidden
in the Windows app.
Well, not necessarily. For example, I have mine in a standard error
logging class, and from my Main I call something like:

ErrorLog.Instance.SetupConsoleErrorHandling();

Ok, I just placed mine elsewhere, and it works, as long as I give
Program class access to it.

Hmm, I jus tested my program with Ctrl+F5 (not F5 debug), and an
unhandled exception window pops up. It appears that my handler
doesn't run. But, it does run if I used F5 debug. Strange.
and inside there I subscribe to the events and the ErrorLog class
contains the event handler methods. Nonetheless, that's just because I
wanted a reusable utility. You can also have the method in your main
program .cs file. Nothing wrong with that.

Right, but its best to have a unit handle this that can be reused, I
agree. So, your ErrorLog class adds the handler, and hopefully this
code is run before any other code that could throw an exception.
Finally, I would like to offer some general advice on catching
exceptions: catch only what you can handle. Or, put another way, don't
catch an exception unless you can take some substantial action
regarding it. There are other threads in this newsgroup on exception
handling... when and how to catch an exception, but I wanted to point
that out because it explains why you (almost) never catch (Exception
ex): because it's very rare that you can take some intelligent action
with any exception that could possible happen.

Yes, I agree. And my main concern was exceptions for things that are
bound to happen, such as int.Parse() or dealing with network traffic,
who knows what data may be passed into these functions, or what
network errors may result. So, in these case, I do want to handle ALL
errors gracefully. But, it seemed ugly to write 5 exceptions handlers
OR catch all excpetions with catch (Exception ex). For int.Parse, I
can use int.TryParse. For networkd traffic, it really seems ok to
catch everything. It'd be different if all the possible exceptions
were under the same exception type, but they are not.
The exception to that rule, of course, being logging, and that's what
global exception handlers are for.

Right.

Zytan
 
B

Bruce Wood

Yes, I agree. And my main concern was exceptions for things that are
bound to happen, such as int.Parse() or dealing with network traffic,
who knows what data may be passed into these functions, or what
network errors may result. So, in these case, I do want to handle ALL
errors gracefully. But, it seemed ugly to write 5 exceptions handlers
OR catch all excpetions with catch (Exception ex). For int.Parse, I
can use int.TryParse. For networkd traffic, it really seems ok to
catch everything. It'd be different if all the possible exceptions
were under the same exception type, but they are not.

With respect to something like Int.Parse, you probably want to catch
those exceptions (of course, in .NET 2.0 you would use TryParse
instead), because you can usually recover from them: assign a default
value or whatever.

Keep in mind that by the time your global exception handler is called,
your application is toast. Dead. RIP. The global exception handler is
simply your last chance to log some information before your
application is torn down. You cannot use it to, as you say, "handle
all errors gracefully".

However, you really can't write an application that handles "all
errors gracefully": how would you handle an "out of memory" exception,
for example, or a network failure? I mean, you could, but that would
be one heck of a robust application.

If you really do want to do something to gracefully recover from an
error then you need an exception handler for that. If you want to
gracefully recover _and_ log then you need to call a logging routine
from inside the exception handler. The global exception handler is for
those exceptions that your application can't handle, but you want to
record why it is that your application exploded and died.
 
Z

Zytan

With respect to something like Int.Parse, you probably want to catch
those exceptions (of course, in .NET 2.0 you would use TryParse
instead), because you can usually recover from them: assign a default
value or whatever.
Yes.

Keep in mind that by the time your global exception handler is called,
your application is toast. Dead. RIP. The global exception handler is
simply your last chance to log some information before your
application is torn down. You cannot use it to, as you say, "handle
all errors gracefully".
Yes.

However, you really can't write an application that handles "all
errors gracefully": how would you handle an "out of memory" exception,
for example, or a network failure? I mean, you could, but that would
be one heck of a robust application.
Exactly.

If you really do want to do something to gracefully recover from an
error then you need an exception handler for that. If you want to
gracefully recover _and_ log then you need to call a logging routine
from inside the exception handler. The global exception handler is for
those exceptions that your application can't handle, but you want to
record why it is that your application exploded and died.

Yes, I follow exactly. Thanks,

http://www.pluralsight.com/blogs/craig/archive/2004/06/13/1455.aspx
This article claims that this code catches all unhandled exceptions:

[STAThread] static void Main() {
Application.ThreadException += new
System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form1());
}

private void button1_Click(object sender, System.EventArgs e) {
throw new Exception("Whoops");
}

private static void Application_ThreadException(object sender,
System.Threading.ThreadExceptionEventArgs e) {
MessageBox.Show(e.Exception.Message);
}

Note it uses
Application.ThreadException += new ...
instead of your
AppDomain.CurrentDomain.UnhandledException +=new ...

You mentioned ThreadException, but now I'm confused. Why do these
both do the same thing?

Yours appears to NOT stop the windows dialog from appearing (when run
NOT in the debugger), whereas his code will stop it from appearing.
But, when using the debugger, yours will run BEFORE the debugger grabs
it, and his will not.

Zytan
 
T

Todos Menos [MSFT]

in my opinion, vb6 error handler was much superior than this managed
crap.. i mean seriously-- it's a lot less verbose

Public Sub MySub
on error goto errhandler



CleanExit:
exit sub
ErrHandler:
Select Case Err.number
Case 12345, 1224334
resume cleanexit
case else
msgbox error$
resume cleanexit
end Select
End Sub
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Zytan said:
Note it uses
Application.ThreadException += new ...
instead of your
AppDomain.CurrentDomain.UnhandledException +=new ...

You mentioned ThreadException, but now I'm confused. Why do these
both do the same thing?

UnhandledException catches any unhandled exception in the application,
while ThreadException only catches unhandled exceptions that occur in
Windows Forms threads.
 
B

Bruce Wood

in my opinion, vb6 error handler was much superior than this managed
crap.. i mean seriously-- it's a lot less verbose

Public Sub MySub
on error goto errhandler

CleanExit:
exit sub
ErrHandler:
Select Case Err.number
Case 12345, 1224334
resume cleanexit
case else
msgbox error$
resume cleanexit
end Select
End Sub

Well, yeah, sort of in the same way that GOTO is much less verbose
than all of this complicated for / foreach / while garbage. Don't even
get me started about all of those wordy function headers with
parameters and stuff... when you can just make everything global and
access it from anywhere. :)

The problem with VB6 error handling is that at _any_ point in your
code, control can magically jump to your error handler subroutine
(hey, the syntax even _says_ goto), run some code, and then slip
quietly back into the control flow of your program as if nothing
happened.

Just like GOTO, it's great when it works, and a bitch to figure out
what on earth is going on when it doesn't. Like GOTO it can be used
responsibly to great effect, or horribly abused to create
incomprehensible code.

Been there, done that. I'm happier with the way things work in .NET,
thanks.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

In my opinion, VB6 error handling was far inferior.

Shorter code is not always better code. What's difficult about
programming is not typing in the commands, so how much you have to type
has little impact on the efficiency of a programmer.

Besides, is it really more verbous?

This would roughly resemble the error handling in your VB6 example:

try {

} catch (IOException) {
} catch (FormatException) {
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}

This is 108 characters compared to 158 (not counting tabs and line
breaks). Unless I have forgotten most of my math, that is much less, not
much more.

Handling different error types is built into the exception model, while
in VB6 you have to use a Select Case to determine the error type. Also
"IOException" says a lot more than "12345".

Exception handling fits well into the structure of the code, while in
VB6 error handling you have to jump back and forth in the code.
Spaghetti code is always harder to follow.
 
T

Todos Menos [MSFT]

In my opinion; C# error handling sucks.

managed error handling sucks.

on error goto errhandler was and is, far superior-- in every fashion

I heard that we're removing TRY CATCH in the next version of Visual
Studio, it should be out next month

-Todos
 
T

Todos Menos [MSFT]

you can have multiple try catch blocks with vb6 also

with managed error handling you have to reinvent the wheel.. so that
you can then 'reinvent the wheel' ad nauseum (sp?)



I'm much happier.. oh wait a second, Vista doesn't run .NET but it
does run VB6? ROFL

and btw; kid-- if you think that .NET is so sweet-- why don't u kindly
explain to me 'how I can tell what version of the framework is on this
machine X right here, underneath my desk.'

I'll bet you $10 you don't give me a good, solid answer ROFL
 
T

Todos Menos [MSFT]

then learn how to program bugfree?

uh.. instead of writing pointers, write a friggin UI?

VB has had a superior interface for 15 years.. your C# crap was never
invented

-Todos
 
T

Todos Menos [MSFT]

try {



} catch (IOException) {
} catch (FormatException) {
} catch (Exception ex) {


MessageBox.Show(ex.Message);


}


ErrHandler:
Select Case Err.number
Case -1 to -2130000000
resume cleanexit
case else
msgbox error$
resume cleanexit
end Select
End Sub
 

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