代码之家  ›  专栏  ›  技术社区  ›  Grokys

在.NET中捕获基异常类

  •  19
  • Grokys  · 技术社区  · 16 年前

    我一直听到这个

    catch (Exception ex)
    

    编辑:

    人们说我应该仔细检查调用堆栈并具体处理错误,因为例如StackOverflow异常无法得到有意义的处理。然而,停止这一进程是关键 最差的

    此外,尽管我尽了最大努力来解决所有可能抛出的异常,但在大型代码库中,我可能会错过一些。对于大多数人来说,最好的防御措施仍然是通知用户。

    16 回复  |  直到 16 年前
        1
  •  32
  •   Rasmus Faber    16 年前

    坏习惯是

    catch (Exception ex){}
    

    和变体:

    catch (Exception ex){ return false; }
    

    在顶层捕获所有异常并将其传递给用户(通过记录它们或将它们显示在消息框中,具体取决于您是在编写服务器应用程序还是客户端应用程序),这正是正确的做法。

        2
  •  20
  •   John Rudy    16 年前

    我发现关于泛型捕获总是不好的论点过于教条。他们和其他人一样,有自己的位置。

    那个地方是 您的库代码,也不是您为应用程序自定义开发的类。正如许多人提到的,这个地方是应用程序的最高级别,如果 任何 引发异常,很可能是意外的。

    这是我的一般规则(和所有规则一样,它是在适当的时候被打破的):

    我在一个应用程序中使用类和自定义库来完成大部分提升。这是基本的应用程序架构——请注意,这是非常基本的。这些人试图处理尽可能多的异常,如果他们真的不能继续,就把最具体的类型返回到UI。

    在UI中,我总是从事件处理程序中获取所有信息。如果有捕获特定异常的合理预期, 我可以对此做些什么,然后捕获特定的异常并优雅地处理它。但是,这必须在catch all之前,因为.NET将只使用与您的异常匹配的第一个异常处理程序。(总是从最具体到最一般的顺序!)

    一网打尽有它的位置。那个地方不是为了隐藏异常,那个地方不是为了尝试和恢复(因为如果你不知道你捕获了什么,你怎么可能恢复),那个地方不是为了防止错误显示给用户,同时允许你的应用程序在未知和坏状态下继续执行。

    如果你在较低的级别上没有设计良好、防护良好的防御措施,那么这是一种糟糕的做法,而且事实确实如此 非常 在较低级别上的不良做法,但作为最后手段,它(在我看来)不仅是可以接受的,而且通常是正确的做法。

        3
  •  12
  •   aku    16 年前

    当我看到

    catch (Exception ex)
    


    1) 第三方组件抛出异常(该死的是它的作者)

    如果你发现有很多不同类型的异常会发生,这是一个坏设计的好迹象。

    我不同意Armin Ronacher的观点。如果引发StackOverflow异常,您将如何处理?尝试执行其他操作可能会导致更糟糕的后果。只有当您能够以有意义和安全的方式处理异常时,才能捕获异常。捕获系统。覆盖的异常 范围 对可能例外情况的分析是非常错误的。即使你在扔它。

        4
  •  7
  •   brock.holum    16 年前

    在代码的最高级别捕获异常是完全有意义的。只要不需要根据异常的类型执行任何不同的逻辑,就可以捕获基本异常类型。

    另外,请确保您显示的是友好的常规错误消息,而不是实际的异常消息。这可能导致安全漏洞。

        5
  •  4
  •   JacquesB    16 年前

    在应用程序的顶层 ,这就是你正在做的。

    ,捕捉基本异常几乎总是错误的。特别是在图书馆,这将是非常糟糕的做法。

        6
  •  3
  •   workmad3    16 年前

    从某种意义上说,你不应该在任何地方都这样做,这是一种不好的做法。

    在这种情况下,我认为这是唯一合理的解决方案,因为你的例外可能是真正的任何事情。唯一可能的改进是在捕获特定错误情况下的所有内容之前添加额外的处理程序,在这些情况下,您可以对异常进行处理。

        7
  •  2
  •   Armin Ronacher    16 年前

    如果你提出了一些你不能正确处理的异常,那也没关系。如果您只是捕获异常,您可能会在代码中隐藏您不期望的错误。如果捕获异常以显示它们(并绕过die和print回溯到stderr行为),这是完全可以接受的。

        8
  •  2
  •   MusiGenesis    16 年前

    我认为海报所指的是这样的异常处理:

    try {something} catch (SqlException) {do stuff} catch (Exception) {do other stuff}
    

    传统观点认为,这是处理异常的正确方法(单独捕获(exception ex)是不好的)。在实践中,这种方法并不总是有效的,尤其是当您使用其他人编写的组件和库时。

    根据组件在开发环境中的行为,这些组件通常会在生产环境中引发与代码所期望的不同类型的异常,即使两种环境中的基本问题是相同的。这是ASP.NET中一个非常常见的问题,经常导致我使用裸捕获(Exception ex)块,它不关心抛出的异常类型。

    结构化异常处理在理论上是一个很好的想法。实际上,在您控制的代码域中,它仍然是一个好主意。一旦你介绍了第三方的东西,它 不太好用。

        9
  •  2
  •   torial    16 年前

    我们经常使用Catch-ex作为异常(VB.Net变体)。我们记录它,并定期检查我们的日志。追查原因,解决问题。

    我认为作为特例的特例是完全可以接受的 一旦

        10
  •  0
  •   blowdart    16 年前

    不在这种情况下,如果你不想停止程序,你就没有别的办法了,只要你正确地登录,而不是把它藏在希望中,那么在顶层是正确的地方 咧嘴笑

        11
  •  0
  •   Ben Fulton    16 年前

    重要的是了解异常在应用程序中的路径,而不是随意抛出或捕获它们。例如,如果捕获的异常内存不足怎么办?您确定在这种情况下会显示对话框吗?但定义一个最后的例外点并说您 从不 希望错误传播超过该点。

        12
  •  0
  •   ottoflux ottoflux    16 年前

    您应该捕获与您正在执行的操作相关的异常。如果您查看您调用的方法,您将看到它们抛出了哪些异常,并且您希望对这些异常保持更具体的描述。您应该有权知道您调用的方法可能引发哪些异常,并适当地处理它们。

    和总比有一个大的尝试捕捉好,在你需要捕捉的地方尝试捕捉。

    try {
       myThing.DoStuff();
    }
    catch (StuffGoneWrongException ex) {
       //figure out what you need to do or bail
    }
    

    也许不是很拥挤,但这取决于你在做什么。记住,这项工作不仅仅是编译它并将它放在某人的桌面上,你还想知道如果某个东西发生了什么故障以及如何修复它。(在此处插入有关跟踪的信息)

        13
  •  0
  •   stefano m    16 年前

    很多时候捕获异常是为了释放资源,如果(重新)抛出异常并不重要。在这些情况下,您可以避免尝试捕捉:

    1) 对于一次性物品,您可以使用“使用”关键字: { //代码 } 一旦您超出了使用范围(正常情况下、通过返回语句或异常),就会自动对对象调用Dispsose方法。换句话说,这就像try/finally构造。

    我希望我能帮助你!

        14
  •  0
  •   MatthewMartin muthu    16 年前

    最差的

    如果您可以通过运行不同的代码(使用try/catch作为控制流)、重试、等待和重试、使用不同但等效的技术(即回退方法)重试来处理异常,那么请务必这样做。

    替换错误消息和记录日志也很好,除非是伪礼貌的被动攻击性“联系您的管理员”(当您知道没有管理员时,如果有管理员,则管理员无法对其执行任何操作!),但是在您这样做之后,应用程序应该结束,即,与未处理的异常相同的行为。

    另一方面,如果您打算通过将用户返回到可能破坏其状态的代码线程来处理异常,我认为这更糟糕

    如果我在确定我可以从哪些帐户取款的模块中遇到意外异常,我是否真的要记录并报告异常并将用户返回到取款屏幕?据我们所知,我们刚刚授予他从所有账户中提款的权利!

        15
  •  0
  •   Xbit Xbit    15 年前

    还将该详细信息异常消息放入日志文件中。

        16
  •  -1
  •   Abbas Bura Chuhadar    11 年前

    我一直在处理一些例外情况,下面是我目前遵循的实现结构:

    1. 在Try/Catch之外,将所有内容暗显为Nothing/String.Empty/0等。
    2. 将Try/Catch中的所有内容初始化为所需的值。
    3. 几乎总是抛出异常
    4. 杀死你在最后一个街区中变暗的所有物体

    最近我认为不“正确”处理异常是可以接受的一个例子是使用通过HTTP GET传递到页面的GUID字符串(strGuid)。我 能够 在调用新GUID(strGuid)之前,我们实现了一个检查GUID字符串有效性的函数,但以下操作似乎相当合理:

    Dim myGuid As Guid = Nothing
    
    Try
        myGuid = New Guid(strGuid)
        'Some processing here...
    
    Catch ex As FormatException
        lblError.Text = "Invalid ID"
    
    Catch ex As Exception 
        Throw
    
    Finally
        If myGuid IsNot Nothing Then
            myGuid = Nothing
        End If
    
    End Try