General Catch Block

C# requires that any object that code throws must derive from System.Exception. However, this requirement is not universal to all languages. C++, for example, allows any object type to be thrown, including managed exceptions that don’t derive from System.Exception. All exceptions, whether derived from System.Exception or not, will propagate into C# assemblies as derived from System.Exception.7 The result is that System.Exception catch blocks will catch all exceptions not caught by earlier blocks.

C# also supports a general catch block (catch{ }) that behaves identically to the catch(System.Exception exception) block, except that there is no type or variable name. Also, the general catch block must appear last within the list of catch blocks. Since the general catch block is identical to the catch(System.Exception exception) block and the general catch block must appear last, the compiler issues a warning if both exist within the same try/catch statement because the general catch block will never be invoked.

AdVanced Topic
General Catch Block Internals

The Common Intermediate Language (CIL) code corresponding to a general catch block is, in fact, a catch(object) block. Thus, regardless of the type thrown, the general catch block will catch it. Interestingly, it is not possible to explicitly declare a catch(object) exception block within C# code. Therefore, there is no means of catching a non–System.Exception-derived exception and having an exception instance to scrutinize.

In fact, unmanaged exceptions from languages such as C++ generally result in System.Runtime.InteropServices.SEHException-type exceptions, which derive from the System.Exception type. Therefore, not only can the unmanaged type exceptions be caught using a general catch block, but the non–System.Exception-managed types that are thrown can be caught as well—for instance, types such as string.

Guidelines for Exception Handling

Exception handling provides much-needed structure to the error-handling mechanisms that preceded it. However, it can still lead to some unwieldy results if used haphazardly. The following guidelines offer some best practices for exception handling.

AVOID exception reporting or logging lower in the call stack.
DO NOT over-catch. Exceptions should be allowed to propagate up the call stack unless it is clearly understood how to programmatically address those errors lower in the stack.
CONSIDER catching a specific exception when you understand why it was thrown in a given context and can respond to the failure programmatically.
AVOID catching System.Exception or System.SystemException except in top-level exception handlers that perform final cleanup operations before rethrowing the exception.
DO use throw; rather than throw <exception object> inside a catch block.
DO use exception filters to avoid rethrowing an exception from within a catch block.
DO use caution when rethrowing different exceptions.
AVOID throwing exceptions from exception filters.
AVOID exception filters with logic that might implicitly change over time.


7. Starting with C# 2.0.
8. Starting with Common Language Runtime (CLR) 4. Prior to CLR 4, code should catch such exceptions only to run cleanup or emergency code (such as saving any volatile data) before shutting down the application or rethrowing the exception with throw;.
{{ snackbarMessage }}