[FxCop.设计规则]12. 不要捕获所有异常

12.     不要捕获所有异常

翻译概述:

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

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

原文引用:

Do not catch general exception types<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

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#]

None.gif using  System;
None.gif
using  System.IO;
None.gif 
None.gif
namespace  DesignLibrary
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
// Creates two violations of the rule.
InBlock.gif
    public class GenericExceptionsCaught
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        FileStream inStream;
InBlock.gif        FileStream outStream;
InBlock.gif 
InBlock.gif        
public GenericExceptionsCaught(string inFile, string outFile)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                inStream 
= File.Open(inFile, FileMode.Open);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch(SystemException e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(
"Unable to open {0}.", inFile);
ExpandedSubBlockEnd.gif            }

InBlock.gif 
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                outStream 
= File.Open(outFile, FileMode.Open);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(
"Unable to open {0}.", outFile);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif 
InBlock.gif    
public class GenericExceptionsCaughtFixed
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        FileStream inStream;
InBlock.gif        FileStream outStream;
InBlock.gif 
InBlock.gif        
public GenericExceptionsCaughtFixed(string inFile, string outFile)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                inStream 
= File.Open(inFile, FileMode.Open);
ExpandedSubBlockEnd.gif            }

InBlock.gif 
InBlock.gif            
// Fix the first violation by catching a specific exception.
InBlock.gif
            catch(FileNotFoundException e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(
"Unable to open {0}.", inFile);
ExpandedSubBlockEnd.gif            }

InBlock.gif 
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                outStream 
= File.Open(outFile, FileMode.Open);
ExpandedSubBlockEnd.gif            }

InBlock.gif 
InBlock.gif            
// Fix the second violation by re-throwing the generic 
InBlock.gif            
// exception at the end of the catch block.
InBlock.gif
            catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(
"Unable to open {0}.", outFile);
InBlock.gif                
throw;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}


[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++]

None.gif # using   < mscorlib.dll >
None.gif
using   namespace  System;
None.gif
using   namespace  System::IO;
None.gif 
None.gif
namespace  DesignLibrary
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
// Creates two violations of the rule.
InBlock.gif
    public __gc class GenericExceptionsCaught
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        FileStream
* inStream;
InBlock.gif        FileStream
* outStream;
InBlock.gif 
InBlock.gif    
public:
InBlock.gif        GenericExceptionsCaught(String
* inFile, String* outFile)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                inStream 
= File::Open(inFile, FileMode::Open);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch(SystemException* e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console::WriteLine(S
"Unable to open {0}.", inFile);
ExpandedSubBlockEnd.gif            }

InBlock.gif 
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                outStream 
= File::Open(outFile, FileMode::Open);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch(Exception* e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console::WriteLine(S
"Unable to open {0}.", outFile);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }
;
InBlock.gif 
InBlock.gif    
public __gc class GenericExceptionsCaughtFixed
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        FileStream
* inStream;
InBlock.gif        FileStream
* outStream;
InBlock.gif 
InBlock.gif    
public:
InBlock.gif        GenericExceptionsCaughtFixed(String
* inFile, String* outFile)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                inStream 
= File::Open(inFile, FileMode::Open);
ExpandedSubBlockEnd.gif            }

InBlock.gif 
InBlock.gif            
// Fix the first violation by catching a specific exception.
InBlock.gif
            catch(FileNotFoundException* e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console::WriteLine(S
"Unable to open {0}.", inFile);
ExpandedSubBlockEnd.gif            }

InBlock.gif 
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                outStream 
= File::Open(outFile, FileMode::Open);
ExpandedSubBlockEnd.gif            }

InBlock.gif 
InBlock.gif            
// Fix the second violation by re-throwing the generic 
InBlock.gif            
// exception at the end of the catch block.
InBlock.gif
            catch(Exception* e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console::WriteLine(S
"Unable to open {0}.", outFile);
InBlock.gif                
throw;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }
;
ExpandedBlockEnd.gif}

None.gif


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。第二段逻辑将异常重新抛出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值