Exception type name does not end in Exception
ID |
vbnet.maintainability.exception_suffix |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
medium |
Remediation Effort |
low |
Resource |
Naming |
Language |
VB.NET |
Description
Reports a type that derives from an exception type whose own name does not end in Exception - InvalidOrder rather than InvalidOrderException, ShipmentFailure rather than ShipmentFailureException. The base type is recognized from the Inherits clause, so Inherits Exception, Inherits System.Exception, Inherits ApplicationException and Inherits InvalidOperationException all make the declaring type an exception. Names that end in another failure word, such as Error or Failure, are reported as well, because the convention names exactly one suffix. This is a convention rule and is reported at informational severity.
Rationale
Exception types are unusual in that they are almost never read at their declaration - they are read in Catch clauses and in Throw statements, written by developers who did not define them, often while looking at a stack trace rather than at source. The suffix is what makes those places legible: Catch ex As InvalidOrderException states plainly what kind of thing is being handled, while Catch ex As InvalidOrder reads as though a domain object were being caught, and a stack trace or a log line containing Ordering.InvalidOrder gives an on-call reader no signal that it names a failure at all. The suffix is also what makes exception types findable: a developer looking for the failures a component can raise searches for *Exception, and a type without the suffix is invisible to that search and to every code-completion list filtered the same way. A type named OutOfStockError is worse than merely unconventional, because Error in .NET suggests the unrecoverable Error-style conditions of other platforms, and readers coming from Java or JavaScript will draw exactly the wrong conclusion about whether it should be caught.
The following code illustrates the pattern detected by this rule:
Namespace Ordering
' BAD: an exception type whose name does not say so.
' FLAGGED: Exception type name does not end in Exception
Public Class InvalidOrder
Inherits ApplicationException
Public Sub New(ByVal message As String)
MyBase.New(message)
End Sub
Remediation
Rename the type so that it ends in Exception: InvalidOrder becomes InvalidOrderException, ShipmentFailure becomes ShipmentFailureException and OutOfStockError becomes OutOfStockException - drop the competing failure word rather than stacking it, so ErrorException never appears. Use the rename refactoring in the IDE so that every Catch clause, Throw statement and documentation reference is updated in the same step. While renaming, check the rest of the exception contract, which is usually incomplete on a type named this way: derive from Exception rather than the obsolete ApplicationException, provide the three standard constructors - parameterless, message, and message plus inner exception - and mark the type <Serializable> if it can cross an application-domain or process boundary. If the type is not really an exception, do not rename it: make it a plain result or state object and stop deriving from an exception type.