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

  • 相关阅读:
    RUST实践.md
    redis.md
    opencvrust.md
    aws rds can't connect to mysql server on 'xx'
    Foundation ActionScript 3.0 With Flash CS3 And Flex
    Foundation Flash Applications for Mobile Devices
    Flash Mobile Developing Android and iOS Applications
    Flash Game Development by Example
    Actionscript 3.0 迁移指南
    在SWT中非UI线程控制界面
  • 原文地址:https://www.cnblogs.com/Cajon/p/177912.html
Copyright © 2020-2023  润新知