Rachel Suddeth said:
<sigh> and yet we're supposed to know at all times what exceptions can be
thrown...
I actually don't make the assumption that I know which *specific* exceptions
will be thrown, only that *an* exception can be thrown. I try to structure
the subsystems so that I know the path that exceptions will take as it
propagates through the system. There are situations where I will catch
specific exceptions and try to handle them but I've found that there are
more exceptions I did not anticipate then there are that I can account for.
Sometimes I think that events are only not random in the same sense that
nothing is ever random. Everything behaves the way it does for some
reason, according to some set of rules (pysical laws, whatever), but when
a stystem is so complex that the behavior of a particular event is
unpredictable, then it is considered random.
I quite agree. Chaos theory rules...
I'm sure it is just my frustration at an unproductive day, but doesn't it
seem that the monstrous set of events that comes built in with our .NET is
approaching that level of complexity? I wonder if it's really simpler and
easier to learn than reading a straightforward message loop...
I don't see this as a .NET problem but more as a system problem. The
combination of .NET, the COM/C++ libs it is built on, and the windowing
system below it, is incredibly complex. Even a straight message loop really
isn't so straight when you trace the passage of an event all the way from
the hardware device that originally generated the event to the trap handler
to the interrupt handler in the device driver, through the kernel, up to
user mode, up to the windows subsystem, etc.
and that is where exceptions come in. If you don't force validation in
every interior function, you could let exceptions go, they will help to
catch those times where you forget to validate something you should've.
Ugh, that contradicts my previous response doesn't it? You see why no one
can agree on how to do error handling? I can't even agree with myself.
And that's the rub. No matter how well written the code there are always
unforseen conditions that the code did not anticipate; foolproof code isn't
proof against all fools.
There's an inherent tension between the desire to centralize code and
eliminate duplication versus bullet-proofing every method that performs
sensitive operations. There isn't a single design that will work for all
systems - the requirements of the system should drive it, not some ivory
tower notion of the proper way of writing code. In mission critical software
I've written a lot of self-defensive code to guard against internal errors,
and sure enough those errors happen. It might only catch a one-in-a-million
bug, and perhaps I'm too paranoid, but I'd rather err on the side of safety
rather then assume the best. I think this matters more the more that the
code interacts with outside systems.
They key is to find a system that will do these two things.
1) It will not send the user multiple messages about the same error.
2) When it does send messages to the user, they will mean something (that
is, they will not say "object not set to an instance." That not only means
nothing to the user, it will mean nothing to the programmer if the user
reports it.
I agree! The problem is not that there is no information but that the
information is either misleading or so incomplete that it is very difficult
to do much with. I really don't want to have to do a core dump, hook up
windbg and trace through system data structures just to determine that an
array index was off by 1!
In my exception management layer I wrote a PublishOnCreate method which
determines if the exception is being thrown for the first time or is being
wrapped and rethrown - it publishes it at the initial throw site and not at
the intermediate sites. Then at the final handler I publish it again - this
captures the initial exception and also the final disposition at the module
boundary, including all the context information that had been added. I do
this double-publish to ensure I have a record even if an exception is
accidently swallowed and ignored.
I haven't worked out my strategy yet for Whidbey. There are some new events
that you can subscribe to that get fired whenever an exception is thrown at
all - this seems like a promising avenue to use for ensuring that exceptions
do not get dropped or lost, but it also has the potential for swamping a
system.
He won't know which of the 65,482 objects in his program wasn't set to an
instance, nor will he even know where it wasn't set because if I'm not
mistaken, the user doesn't get the stack trace in production code.)
Hmmm, it may not be able to provide lines numbers and source file names, but
a stack trace should always be available.