【问题标题】:Using bool (return Type) to handle exceptions or pass exception to client?使用 bool(返回类型)处理异常或将异常传递给客户端?
【发布时间】:2010-11-29 17:25:13
【问题描述】:

我正在尝试找出处理异常的最佳方法,我的应用程序有很多层,并开始使用返回类型 BOOL,即如果失败则返回 False,如果成功则返回 True..

这在 SaveMyRecord(somerecord); 这样的方法中非常有效。因为我正在传递值并且不需要返回任何内容,所以我可以使用 bool 的返回类型来指示它是否成功。

但后来它让我想到像 GetMyRecord() 这样的东西实际上返回 IQueryable 的类型,因此我不能使用 bool 来告诉我它是否失败。

问题是我正在处理我的很多错误,它们发生在 try 和 catch 中,因此不希望客户端收到异常。

也许有更好的方法,然后我开始考虑使用 OUT 参数,但这意味着我需要更改所有方法的签名并添加额外的参数..

也许我应该将异常传递回客户端并在那里处理它?

是否有一些标准或任何文档来推荐最佳实践?

【问题讨论】:

  • 您在服务器端和客户端使用什么?例如:WCF、ASMX、WinFoms、WebForms。
  • 如果你结合@AlfredMeyers 和@dove 所说的话,你就会得到我打算给你的答案。我不会将他们所说的内容添加到一个综合答案中,而是要同时阅读它们。最重要的是,尽管要阅读。为他们每个人 +1。
  • 服务是否面向互联网?有哪些安全要求?您是否担心通过异常暴露潜在的不安全信息?
  • @AlfredMyers - 我使用了许多层,1 在 wcf 后面

标签: c# .net exception exception-handling try-catch


【解决方案1】:

MS 似乎喜欢的一个常见模式是有一个返回“int”的 ComputeSomething() 方法和一个接受对整数的引用并返回布尔值的 TryComputingSomething() 方法。后者在成功时将其计算存储在传入的变量中并返回 True;如果由于“预期”原因而失败,则返回 False。请注意,任一例程中的意外失败都可能引发异常。

在某些情况下,使用不同的模式可能会有所帮助,并让例程接受委托以在出现问题时调用。该委托可能会返回异常,或者导致底层例程返回 false,或者可能执行其他操作。请注意,在委托运行时,信息将可用,这些信息将在捕获任何异常之前被销毁。例如,如果例程应该从文件中读取行并将字符 20-37 转换为日期,那么在出现解析错误时记录整个输入行可能会有所帮助。使用传入的委托,可以做到这一点;如果没有这样的东西,那就更难了。

【讨论】:

    【解决方案2】:

    冒泡异常给客户并在那里处理。一定要从头到尾详细地传递它。大多数最佳实践几乎完全同意这一点,最终总是在外围处理,在这种情况下是 CLIENT,但在其他情况下可能是 Web 服务。

    仅捕获如果您想记录它,添加更多信息或尝试并恢复一个特殊的例外。在每种情况下,您要么将原始异常作为内部异常,要么简单地“抛出”原始异常,并且正如 cmets 中所指出的那样,不要“抛出 ex”

    这个问题几乎重复,您会发现很多现有的关于 SO 的问题得到了很好的回答。我昨天才回复similar one

    【讨论】:

    • 就只捕获日志而言,只要您在日志记录后也重新抛出异常就可以了。如果您这样做,请确保只使用 throw 语句而不是 throw ex,这样您就不会破坏堆栈跟踪。
    • @Scott 绝对。此外,如果您要添加更多信息,则将原始异常作为您创建的新异常的内部异常。如果你在n次后无法恢复,那么就按你说的扔。以为你知道这一切;)但认为它可能会帮助其他读者
    • 同意 Scott 和个人经验:如果您尝试构建一个非常复杂的应用程序,其中您的错误条件基于布尔返回值,您很快就会看到意大利面条式编码并意识到您知之甚少关于从几个月前编写的子程序的深处返回错误时出了什么问题。基本问题是,返回值必须被线程化到可以通过许多层处理它的代码,而异常“冒泡”到可以通过设计处理的地方。
    • 感谢大家的建议! - 我现在要应用它!!.. 基本上我不会使用 try - catch 和 Log and throw;重新抛出相同的错误,以便它冒泡到我将处理它的客户端..
    【解决方案3】:

    推荐并认为是最佳实践的方法是使用异常。您可以(并且应该)阅读Framework Design Guidelines (2nd Ed.),其中包含有关异常和尝试解析模式的指南。

    使用返回码(数字或布尔值)存在一些问题,其中两个最大的问题是:

    • 很容易被程序员忽略/忽略。
    • 不能在所有情况下都使用。如果你的构造函数失败会发生什么?您无法从构造函数显式返回值。

    至于什么时候处理异常,你应该只在你可以对异常做一些有意义的事情时才处理它们。总是处理异常以便客户端永远不会看到它们的问题在于,您最终可能会处理一个您不应该遇到的异常,并在以后导致更多问题(例如实际丢失数据)。

    【讨论】:

      【解决方案4】:

      你应该开始阅读Design Guidelines for Exceptions

      然后,根据您的情况,您应该考虑其他因素,例如异常屏蔽。

      例如:如果您使用 Web 服务(ASMX 或 WCF)作为后端,您可能需要查看 Improving Web Services Security 并阅读有关异常处理的部分。

      【讨论】:

        【解决方案5】:

        如果一个方法不能完成它的工作,它应该抛出一个异常。永远不要因此返回异常。

        【讨论】:

          【解决方案6】:

          这是个好问题!

          不要为异常编码。在大多数情况下,假装它们从未发生过。我在两个地方担心异常:向用户显示错误反馈和资源管理(即在抛出异常时关闭打开的文件)。

          【讨论】:

            猜你喜欢
            • 2011-07-01
            • 1970-01-01
            • 2015-08-18
            • 2019-07-27
            • 2015-04-26
            • 1970-01-01
            • 1970-01-01
            • 2016-10-27
            • 2019-11-09
            相关资源
            最近更新 更多