29.5.08

Error Handling and Exception Guidelines for .NET

Use exceptions only for exceptional cases, not for routine program flow. Exceptions have significant performance overhead.

Guidelines:

  • Pass a descriptive string into the constructor when throwing an exception.
  • Use grammatically correct error messages, including ending punctuation. Each sentence in the description string of an exception should end in a period.
  • If a property or method throws an exception in some cases, document this in the comments for the method. Include which exception is thrown and what causes it to be thrown.
    • Example: Comment for Order.TotalCost property might read "Gets or sets the total cost of an Order. If the TotalCost property is set when the cost should be calculated, an InvalidOperationException is thrown."
  • Use the following exceptions if appropriate:
    • ArgumentException (and ArgumentNull, ArgumentOutOfRange, IndexOutOfRange): Used when checking for valid input parameters to method.
    • InvalidOperationException: Used when a method call is invalid for the current state of an object.
      • Example: TotalCost cannot be set if the cost should be calculated. If the property is set and it fails this rule, an InvalidOperationException is thrown.
    • NotSupportedException: Used when a method call is invalid for the class.
      • Example: Quantity, a virtual read/write property, is overridden by a derived class. In the derived class, the property is read-only. If the property is set, a NotSupportedException is thrown.
    • NotImplementedException: Used when a method is not implemented for the current class.
      • Example: A interface method is stubbed in and not yet implemented. This method should throw a NotImplementedException.
  • Derive your own exception classes for a programmatic scenarios. All new derived exceptions should be based upon the core Exception class.
    • Example: DeletedByAnotherUserException : Exception. Thrown to indicate a record being modified has been deleted by another user.
  • Rethrow caught exceptions correctly.

The following example throws an exception caught and rethrown incorrectly:

catch( Exception ex )
{
LogManager.Publish( ex );
throw ex; // INCORRECT – we lose the call stack of the exception
}

We log all unhandled exceptions in our applications, but may sometimes throw them again to let the higher level systems determine how to proceed. The problem comes in with the throw – it works much better to do this:

catch( Exception ex )
{
LogManager.Publish( ex );
throw; // CORRECT - rethrows the exception we just caught
}

Notice the absence of an argument to the throw statement in the second variation.

The difference between these two variations is subtle but important. With the first example, the higher level caller isn’t going to get all the information about the original error. The call stack in the exception is replaced with a new call stack that originates at the “throw ex” statement – which is not what we want to record. The second example is the only one that actually re-throws the original exception, preserving the stack trace where the original error occurred.

(Source: C# Coding Standards)

Nvidia's GauGan App

NVIDIA's GauGAN AI Machine Learning Tool creates photorealistic images from Simple Hand Doodling http://nvidia-research-mingyuliu.com/...