Do not raise exceptions in filter blocks
TypeName |
DoNotRaiseExceptionsInFilterBlocks |
CheckId |
CA2219 |
Category |
Microsoft.Usage |
Breaking Change |
NonBreaking |
Cause
A method contains a filtered exception handler, and the filter raises exceptions.
Rule Description
When an exception filter raises an exception, the exception is caught by the common language runtime, and the filter returns false. This behavior is indistinguishable from the filter executing and returning false intentionally.
Currently, Visual Basic .NET and the Visual C++ support exception filters.
How to Fix Violations
To fix a violation of this rule, do not raise exceptions in an exception filter.
When to Exclude Warnings
Do not exclude a warning from this rule. There are no scenarios under which an exception raised by an exception filter provides a benefit to the executing code.
Example
The following example shows a type that violates this rule. Note that the filter appears to return false when it throws an exception.
Imports System
Module ExceptionFilter
Public Class FilterTest
' The following function is used as an exception filter.
' Violates rule: DoNotRaiseExceptionsInFilterBlocks.
Public Function AlwaysTrueFilter(label as String) as Boolean
Console.WriteLine("In filter for {0}.", label)
' The following exception terminates the filter.
' The common language runtime does not return the exception to the user.
Throw New ApplicationException("Filter generated exception.")
Return True
End Function
Public Sub ThrowException()
Try
Throw New ApplicationException("First exception.")
' Because the filter throws an exception, this catch clause fails to catch the exception.
Catch e as ApplicationException When Not AlwaysTrueFilter("First")
Console.WriteLine("Catching first filtered ApplicationException {0}", e)
' Because the previous catch fails, this catch handles the exception.
Catch e as ApplicationException
Console.WriteLine("Catching any ApplicationException - {0}", e.Message)
End Try
' The behavior is the same when the filter test is reversed.
Try
Throw New ApplicationException("Second exception.")
' Change the filter test from When Not to When.
' This catch fails.
Catch e as ApplicationException When AlwaysTrueFilter("Second")
Console.WriteLine("Catching second filtered ApplicationException {0}", e)
' This catch handles the exception.
Catch e as ApplicationException
Console.WriteLine("Catching any ApplicationException - {0}", e.Message)
End Try
End Sub
End Class
Sub Main()
Dim test as FilterTest = New FilterTest()
test.ThrowException()
End Sub
End Module
The example produces the following output.
Output
In filter for First. Catching any ApplicationException - First exception. In filter for Second. Catching any ApplicationException - Second exception.