Exception handling guidelines

Exception Throwing

X DO NOT return error codes.

Exceptions are the primary means of reporting errors in frameworks.

✓ DO report execution failures by throwing exceptions.

✓ CONSIDER terminating the process by calling System.Environment.FailFast (.NET Framework 2.0 feature) instead of throwing an exception if your code encounters a situation where it is unsafe for further execution.

X DO NOT use exceptions for the normal flow of control, if possible.

Except for system failures and operations with potential race conditions, framework designers should design APIs so users can write code that does not throw exceptions.

✓ CONSIDER the performance implications of throwing exceptions. Throw rates above 100 per second are likely to noticeably impact the performance of most applications.

✓ DO document all exceptions thrown by publicly callable members because of a violation of the member contract (rather than a system failure) and treat them as part of your contract.

X DO NOT have public members that can either throw or not based on some option.

X DO NOT have public members that return exceptions as the return value or an out parameter.

✓ CONSIDER using exception builder methods.

It is common to throw the same exception from different places. To avoid code bloat, use helper methods that create exceptions and initialize their properties.

Also, members that throw exceptions are not getting inlined. Moving the throw statement inside the builder might allow the member to be inlined.

X DO NOT throw exceptions from exception filter blocks.

When an exception filter raises an exception, the exception is caught by the CLR, and the filter returns false. This behavior is indistinguishable from the filter executing and returning false explicitly and is therefore very difficult to debug.

X AVOID explicitly throwing exceptions from finally blocks. Implicitly thrown exceptions resulting from calling methods that throw are acceptable.

Using Standard Exception Types

Exception and SystemException

X DO NOT throw System.Exception or System.SystemException.

X DO NOT catch System.Exception or System.SystemException in framework code, unless you intend to rethrow.

X AVOID catching System.Exception or System.SystemException, except in top-level exception handlers.

ApplicationException

X DO NOT throw or derive from ApplicationException.

InvalidOperationException

✓ DO throw an InvalidOperationException if the object is in an inappropriate state.

ArgumentException, ArgumentNullException, and ArgumentOutOfRangeException

✓ DO throw ArgumentException or one of its subtypes if bad arguments are passed to a member. Prefer the most derived exception type, if applicable.

✓ DO set the ParamName property when throwing one of the subclasses of ArgumentException.

This property represents the name of the parameter that caused the exception to be thrown. Note that the property can be set using one of the constructor overloads.

✓ DO use value for the name of the implicit value parameter of property setters.

NullReferenceException, IndexOutOfRangeException, and AccessViolationException

X DO NOT allow publicly callable APIs to explicitly or implicitly throw NullReferenceException, AccessViolationException, or IndexOutOfRangeException. These exceptions are reserved and thrown by the execution engine and in most cases indicate a bug.

Do argument checking to avoid throwing these exceptions. Throwing these exceptions exposes implementation details of your method that might change over time.

StackOverflowException

X DO NOT explicitly throw StackOverflowException. The exception should be explicitly thrown only by the CLR.

X DO NOT catch StackOverflowException.

It is almost impossible to write managed code that remains consistent in the presence of arbitrary stack overflows. The unmanaged parts of the CLR remain consistent by using probes to move stack overflows to well-defined places rather than by backing out from arbitrary stack overflows.

OutOfMemoryException

X DO NOT explicitly throw OutOfMemoryException. This exception is to be thrown only by the CLR infrastructure.

ComException, SEHException, and ExecutionEngineException

X DO NOT explicitly throw COMException, ExecutionEngineException, and SEHException. These exceptions are to be thrown only by the CLR infrastructure.

Exceptions and Performance

X DO NOT use error codes because of concerns that exceptions might affect performance negatively.

✓ CONSIDER the Tester-Doer Pattern for members that might throw exceptions in common scenarios to avoid performance problems related to exceptions.

✓ CONSIDER the Try-Parse Pattern for members that might throw exceptions in common scenarios to avoid performance problems related to exceptions.

✓ DO use the prefix "Try" and Boolean return type for methods implementing this pattern.

✓ DO provide an exception-throwing member for each member using the Try-Parse Pattern.

Last updated