exception handling

T

tolisss

Hi

i have setup a global exception handler b4 Application.Run like
Application.ThreadException += new
ThreadExceptionEventHandler(GlobalExceptionProcessing.AppThreadException
);

then after Application.Run(new Form1()); i have setup a global keyboard
hook

my problem is that if an error occured inside keyboardHookProc the
global exception error does not catch it

am i missing something?
 
T

tolisss

i though of that but could not find a way to make my application not die
after handling that event. Is it possible?
 
M

Michael McCarthy

Why in the world would you want to set up a global exception handler?
You should catch exceptions relating to what failed, I don't think
you'll be able to effectively deal with thrown exceptions if you use
some one-size-fits-all technique common to old-school programming.

You can also "assume" that a good portion of the opcode will work, while
code that relies on unknown entities like remote servers etc, may
fail, and those you surround in try/catch... like

try
{
///myunknown routine here
}

catch (Exception ex)
{
Messagebox.Show(ex.message);
}

....like that. You shouldnt be using a single event handler for any
exception that gets thrown in the module.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

While I cannot give you an answer of why it happen I can give you ideas of
how to workaround it.

What if you use a try/catch block inside the hook, if you detect an
exception you could call GlobalExceptionProcessing.AppThreadException
( I think it's a static method , right ? )


Cheers,
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

AFAIK there is no way to prevent the application from finishing. All you can
know is IF the application is finishing or not , IIRC if it's a worker
thread the app does not ends.

Cheers,
 
B

Bruce Wood

In order to have your application "not die," you must catch events
specifically where they happen and handle them there. Once an exception
has made it up the stack to a global event handler like
Thread.ThreadException or AppDomain.UnhandledException, there is no way
to indicate that you want to "go back" to where the exception
originally occurred and continue execution from that point.

All that these global event handlers do for you is give you the
opportunity to handle the unhandled exceptions in your own way before
your application dies, rather than settling for the default behaviour:
for example, inserting code to log the exceptions to a file. They don't
give you the opportunity to control where your application continues
execution, so far as I know.
 
B

Bruce Wood

Why in the world would you want to set up a global exception handler?
You should catch exceptions relating to what failed...

Absolutely not. You should catch exceptions that you know how to deal
with in your local code. For example, if you're trying to convert a
string to a double, and you know it might fail, but you have a default
value, you should catch the exception, set the default value, and allow
execution to continue.

Another example: if you try to call a Web Service and the call fails,
and that particular call isn't critical to your application, you could
catch the exception, warn the user that some information is not
available, and continue execution.

Global event handlers are for all of those other exceptions: the ones
that you can't handle gracefully... the ones that will kill your
application. A global event handler at least lets you tell the user
nicely that something has gone horribly wrong and you have to shut down
now. For example, we use them to display what we want the user to see
(in a MessageBox) but log the gory details to a log file for analysis
by the IS department.

Again, these are exceptions for which the application has no recovery
strategy, and so has to shut down. You should allow them to go
unhandled, and catch them in the global exception handler in order to
do user-friendly things in such a failure situation.
try
{
///myunknown routine here
}
catch (Exception ex)
{
Messagebox.Show(ex.message);
}

This is wrong on two counts. First and most aggrevious, it shows an
exception message to the user (is that going to mean anything to the
user?) and then _merrily carries on_ executing the program, even
thought the "myunknownroutine" _failed_ with an exception! How do you
know that the application _can_ continue functioning if that routine
fails? Is the state of the application such that it can survive that?
Or is everything in an indeterminate state now, a state that will
result in (at best) further exceptions or (at worst) subtle corruption
of your company's database?

The only way you should ever do this is if you _know_ that
"myunknownroutine" really isn't all that important, and if it fails
it's no big deal. In that case, yes, you should catch the exception,
and either silently log it to a file somewhere, or log it to a file and
warn the user that things are less than optimal, but the program can
still keep working.

The second reason that this is wrong is that you should avoid
catch-alls like "catch (Exception ex)". Carrying on with the idea that
you should only catch exceptions that you know are no big deal, do you
really know that _every exception_ that "myunknownroutine" could
possibly throw is no big deal? What about OutOfMemoryException? Do you
really want to catch that one and continue as though nothing happened?
What about InvalidArgumentException, which indicates an error in your
calling code? What if you verify that every exception is, in fact, no
big deal, but then the next revision of the library adds a new
exception? In general, you should catch _specific exceptions_ that you
know you can deal with, and let the other ones go.

There is one situation I've found, though, in which "catch (Exception
ex)" is inevitable. That's when a vendor's documentation about what
exceptions a method throws is lacking. (See the MSDN documentation on
the Crystal .NET stuff for an example of crap doc that doesn't tell you
_anything_ about exceptions.) In cases like this, you really have no
idea which exceptions a method will throw, so you either have to run
some tests and figure out which exceptions you can handle, or decide
that it's no big deal if the method fails and just do "catch (Exception
ex)". I, for example, use this catch-all and just inform the user that
the report couldn't be printed, and then move on. That's one case in
which a method failure is not a problem.

Global exception handlers are not "old-school programming": they are
the recommended way of gracefully shutting down an application that has
failed.
 
M

Michael McCarthy

Bruce said:
Absolutely not. You should catch exceptions that you know how to deal
with in your local code. For example, if you're trying to convert a
string to a double, and you know it might fail, but you have a default
value, you should catch the exception, set the default value, and allow
execution to continue.

Dealing with say, an unavailable resource is a lot like the application
not working at all if it depends on that resource... we catch what we
think may give us an error...

I don't have anything against a clean exit if there is an error that we
don't know what to do with, but I question how the framework may handle
that exception by default... an error message from the framework with
MSIL may not be much worse than a custom error message based on the
thrown exception we have caught.
 
B

Bruce Wood

Usually global exception handlers are used only to log the detailed
message (such as a stack trace or other such information) in a central
log while showing the user a message that says simply, "Something went
wrong. Please contact the IT department."

Generally this is either to make the application look more
professional, or for security reasons (not wanting to publicize the
internal details of your application's architecture in an error
message).

There's really not much else you can do in an global exception handler.
You can't tell the application to continue in any meaningful way (it's
effectively already dead), so they're useful only for logging (and thus
dealing gracefully) with catastrophic errors.
Dealing with say, an unavailable resource is a lot like the application
not working at all if it depends on that resource... we catch what we
think may give us an error...

For any exception, there are really only three cases that I can think
of:

1. The exception indicates a situation from which the application can
reliably recover. A conversion error, a format error, an unavailable
resource that is not critical to the application. In this case, you
_should_ catch the exception, take remedial action, and continue
execution.

2. The exception is one that you can't do anything about at all.
OutOfMemoryException is a good example of this. Don't try to catch the
exception. Let it bubble to the top of the stack and into the global
exception handler. Log it or report it as you wish, and take the
application down.

3. The exception is one that you can't do anything about, but if you
just let it bubble up the stack you will lose valuable contextual
information about what went wrong and the resulting error message,
logged or not, will be next to useless. Catch the exception, log the
appropriate contextual information, then rethrow the exception, or
throw a more meaningful exception that wraps the original exception,
and let that exception bubble up the stack and into the global
exception handler.

This is why most C# programs are full of try...finally blocks, with no
catches. The finally releases resources and does other cleanup if
something fails, but there is no attempt to catch the exceptions, as
there's really nothing useful to do with them at that point in the
code.

At least for the time being (and, given Anders Hejlsberg's outlook on
this probably forever) the C# model of how to deal with exceptions is
very, very different from the Java model. I won't go into how Java
deals with exceptions, but it's a whole different take on the thing. C#
(and .NET in general) encourages more global exception handling, while
Java encourages more local exception handling. After getting used to
the C# way, I have to say that I prefer it (with some caveats).
 
H

Helge Jensen

Bruce Wood wrote:

[lots of stuff]

Amen!
There is one situation I've found, though, in which "catch (Exception
ex)" is inevitable. That's when a vendor's documentation about what
exceptions a method throws is lacking. (See the MSDN documentation on
the Crystal .NET stuff for an example of crap doc that doesn't tell you
_anything_ about exceptions.) In cases like this, you really have no

I rather like to have:

try {
...;
} catch ( Exception e ) {
LogFatalException(e);
throw;
}

at the top of the call-stack.

Of course, Log should preferably not throw any expections itself :)
 
M

Michael McCarthy

Thanks for the terrific response Bruce. It certainly gives one something
to consider when designing on an every day basis, usable, stable, at
least hopfully logical modules.

~Michael.
 
B

Bruce Wood

You're welcome. It occurred to me this morning that on point #3,
exceptions that you can't do anything about, but which should have more
contextual information logged in order to make them useful, you can
also catch the exception, and then throw a new exception that wraps the
original exception, _and adds contextual information_ in the new
exception's message. You can then let the new exception bubble up the
call stack and into the global exception handler, where it will be
logged, along with all of the contextual information it contains.

I do this in several spots, especially when I discover during debugging
that an exception isn't very informative and I need more information
about what happened.
 

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