12.     不要捕获所有异常

翻译概述:

在传统的C++中,对于大多数错误逻辑使用返回错误码的方式来定义。从而使程序逻辑中充斥了大量的条件判断逻辑,严重的影响了代码的可维护性和美观。而异常机制为开发提供了一套相对独立和易管理的错误处理方式,因此,在目前的大多数程序设计语言中都提供了对异常的支持,包括C++

但是,异常属于一个脱离程序逻辑之外的控制流程,因此,对异常的滥用很多时候反而会降低程序逻辑的可维护性和易读性。(相信大多数老程序员都有过在修Bug时毫无原则的添加异常捕获逻辑的经历)而FxCop中的这条规则就实现了对异常捕获滥用的检查。

原文引用:

Do not catch general exception types

TypeName:

DoNotCatchGeneralExceptionTypes

CheckId:

CA1031

Category:

Microsoft.Design

Message Level:

CriticalError

Certainty:

95%

Breaking Change:

NonBreaking


Cause: System.Exception or System.SystemException is caught in a catch statement, or a general catch clause is used.

Rule Description

General exceptions should not be caught.

How to Fix Violations

To fix a violation of this rule, catch a more specific exception, or re-throw the general exception as the last statement in the catch block.

When to Exclude Messages

Do not exclude a message from this rule. Catching general exception types can hide run-time problems from the library user, and can complicate debugging.

Example Code

The following example shows a type that violates this rule and a type that correctly implements the catch block.

[C#]

[FxCop.设计规则]12. 不要捕获所有异常using System;
[FxCop.设计规则]12. 不要捕获所有异常
using System.IO;
[FxCop.设计规则]12. 不要捕获所有异常 
[FxCop.设计规则]12. 不要捕获所有异常
namespace DesignLibrary
}


[Visual Basic]
 

Imports System

Imports System.IO

 

Namespace DesignLibrary

 

    ' Creates two violations of the rule.

    Public Class GenericExceptionsCaught

 

        Dim inStream  As FileStream

        Dim outStream As FileStream

 

        Sub New(inFile As String, outFile As String)

 

            Try

                inStream = File.Open(inFile, FileMode.Open)

            Catch ex As SystemException

                Console.WriteLine("Unable to open {0}.", inFile)

            End Try

 

            Try

                outStream = File.Open(outFile, FileMode.Open)

            Catch

                Console.WriteLine("Unable to open {0}.", outFile)

            End Try

 

        End Sub

 

    End Class

 

    Public Class GenericExceptionsCaughtFixed

 

        Dim inStream  As FileStream

        Dim outStream As FileStream

 

        Sub New(inFile As String, outFile As String)

 

            Try

                inStream = File.Open(inFile, FileMode.Open)

 

            ' Fix the first violation by catching a specific exception.

            Catch ex As FileNotFoundException

                Console.WriteLine("Unable to open {0}.", inFile)

            End Try

 

            Try

                outStream = File.Open(outFile, FileMode.Open)

 

            ' Fix the second violation by re-throwing the generic

            ' exception at the end of the catch block.

            Catch

                Console.WriteLine("Unable to open {0}.", inFile)

            Throw

            End Try

 

        End Sub

 

    End Class

 

End Namespace


[C++]

[FxCop.设计规则]12. 不要捕获所有异常#using <mscorlib.dll>
[FxCop.设计规则]12. 不要捕获所有异常
using namespace System;
[FxCop.设计规则]12. 不要捕获所有异常
using namespace System::IO;
[FxCop.设计规则]12. 不要捕获所有异常 
[FxCop.设计规则]12. 不要捕获所有异常
namespace DesignLibrary


Related Rules

Rethrow to preserve stack details

See Also

Error Raising and Handling Guidelines

引起的原因:

使用catch语句捕获System.ExceptionSystem.SystemException类型的异常,或者使用了无类型catch子句。

 

描述:

不应该捕获所有的异常。

修复:

只捕获部分指定类型的异常,或者在catch语句块的结尾将一半类型的异常重新抛出。

例外:

不要禁用这条规则。捕获所有的异常将会隐藏运行时的一些问题,这样将会使用户调试程序变得复杂。

 

例程:

原文的例子中,分别用三种语言分别演示错误的用法和如何修复这个错误。

其中,类型GenericExceptionsCaught在构造函数中有两段捕获异常的代码,第一段捕获了System.SystemException类型的异常,第二段捕获了所有的异常。

而类型GenericExceptionsCaughtFixed中,演示了如何修正这两段不正确的逻辑,对于第一段逻辑,使用了一个特定类型的异常捕获语句代替捕获SystemException。第二段逻辑将异常重新抛出。

相关文章: