zoukankan      html  css  js  c++  java
  • [FxCop.设计规则]12. 不要捕获所有异常

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

    using System;
    using System.IO;
     
    namespace DesignLibrary
    {
        
    // Creates two violations of the rule.
        public class GenericExceptionsCaught
        
    {
            FileStream inStream;
            FileStream outStream;
     
            
    public GenericExceptionsCaught(string inFile, string outFile)
            
    {
                
    try
                
    {
                    inStream 
    = File.Open(inFile, FileMode.Open);
                }

                
    catch(SystemException e)
                
    {
                    Console.WriteLine(
    "Unable to open {0}.", inFile);
                }

     
                
    try
                
    {
                    outStream 
    = File.Open(outFile, FileMode.Open);
                }

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

            }

        }

     
        
    public class GenericExceptionsCaughtFixed
        
    {
            FileStream inStream;
            FileStream outStream;
     
            
    public GenericExceptionsCaughtFixed(string inFile, string outFile)
            
    {
                
    try
                
    {
                    inStream 
    = File.Open(inFile, FileMode.Open);
                }

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

     
                
    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}.", outFile);
                    
    throw;
                }

            }

        }

    }


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

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

                
    catch(SystemException* e)
                
    {
                    Console::WriteLine(S
    "Unable to open {0}.", inFile);
                }

     
                
    try
                
    {
                    outStream 
    = File::Open(outFile, FileMode::Open);
                }

                
    catch(Exception* e)
                
    {
                    Console::WriteLine(S
    "Unable to open {0}.", outFile);
                }

            }

        }
    ;
     
        
    public __gc class GenericExceptionsCaughtFixed
        
    {
            FileStream
    * inStream;
            FileStream
    * outStream;
     
        
    public:
            GenericExceptionsCaughtFixed(String
    * inFile, String* outFile)
            
    {
                
    try
                
    {
                    inStream 
    = File::Open(inFile, FileMode::Open);
                }

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

     
                
    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(Exception* e)
                
    {
                    Console::WriteLine(S
    "Unable to open {0}.", outFile);
                    
    throw;
                }

            }

        }
    ;
    }


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

  • 相关阅读:
    CodeBlocks 中fopen函数不支持命令 “r”
    【转载】分享一些Qt学习资源,欢迎下载
    【转载】知乎答案----孙志岗----Google 发布了程序员养成指南,国内互联网巨头是否也有类似的指南和课程推荐
    【转载】谷歌公司推荐的程序员必修课(英文教程)
    【转载】张逸--ThoughtWorks(中国)程序员读书雷达
    在windows环境下,为什么要用Notepad++编辑?
    【转载】池建强--趣谈个人建站
    JAVA入门第二季 第一章 类和对象
    CAP理论总结
    分布式通信方式之消息队列之RocketMQ
  • 原文地址:https://www.cnblogs.com/Cajon/p/177912.html
Copyright © 2011-2022 走看看