Perhaps you are missing something important about exceptions, not constructors. Exception propagation goes "above" the usual call/return mechanism bases on the thread stack, it makes a "long jump" (old C/C++ developers in real-mode of Intel CPU might remember the idea) up the stack to the closest catch. So, not that anything failed, the whole context where
x
is created is removed from stack (think "stack unwinding").
Generally, the whole idea in Structured Exception Handling is replaced with something else. There are no "errors", essentially, there are no error statuses. The objects themselves are removed. This is a kind of a time machine: exception propagation jumps execution "back in time", to the moment where the context of
x
was not yet created. Let's compare:
MyType SomeMethod() {
MyType x = new MyType();
return x;
}
with
MyType SomeMethod() {
try {
MyType x = new MyType();
} catch (SomeException) {}
return x;
}
and with
MyType SomeMethod() {
MyType x;
try {
MyType x = new MyType();
} catch (SomeException) {}
return x;
}
and, finally, with
MyType SomeMethod() {
MyType x = null;
try {
MyType x = new MyType();
} catch (SomeException) {}
return x;
}
As you can see, there is no a room for any ambiguity.
Now, in practice, it's the best to use the very first option and avoid catching exceptions too locally. You want to let go. Ideally, exceptions should be caught in very few points, typically pretty far away from the point where they are thrown. That approach helps to isolate exception handling from "normal" processing: exceptions should be processed exceptionally. As Matt T Heffron correctly pointed out in hist important comment (see below), the exceptions should be caught where the exceptional behavior cab be best addressed. I call it "
competency point".
[EDIT: the end of the previous and the next paragraphs have been modified, driven by the comment by Matt T Heffron.]
As a minimalistic "default" exception handling approach, all exceptions should be caught only on the very top of the stack of the stack of each thread. Event-oriented UI is a special case; you need to catch all exceptions in the uppermost loop, the application event loop. When this is done, some exceptions can be could for some special cases, according to the "competency point" approach. The cases when the all the exceptions really should be caught immediately in a very narrow context (as shown in my samples above) are pretty rare; for example, it is pretty typically needed to compensate for some poorly designed APIs with source code unreachable for a patch; in normal situations under the full control of the developers, such technique is best avoided.
Please see my past answers:
How do i make a loop that will stop when a scrollbar reaches the bottom[
^],
Keep a c# windows form application running despite any unhandled exception[
^],
When i run an application an exception is caught how to handle this?[
^],
throw . .then ... rethrowing[
^],
Error Logging and Screen Shot.[
^],
Catching an Exception[
^],
Handling exceptions in class library (dll)[
^],
Exception Details: System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error:...[
^].
—SA