3

假设我们在业务层有以下方法。告诉 UI 层出现问题并给出错误消息的最佳实践是什么?该方法是否应该在正常时返回一个空字符串,否则返回错误消息,还是应该在包装捕获的异常的捕获代码中抛出另一个异常?如果我们选择第二个变体,那么 UI 应该有另一个 try,catch 太多的 try,catch 可能。这是第一个变体的伪代码。

public String updateSomething()
{
   try
   {
      //Begin transaction here
      dataLayer.do1();
      dataLayer.do2();
      dataLayer.doN();
      //Commit transaction code here
   }
   catch(Exception exc)
   {
      //Rollback transaction code here
      return exc.message;
   }

   return "";
 }

这是一个好习惯还是我应该在 catch 中抛出另一个异常(然后该方法将无效)?

4

4 回答 4

5

我喜欢将标准合同从我的业务层返回到我的 UI 层。

它看起来像这样:

public class ServiceOperationResult<T>
{

    public bool Successful
    {
        get; 
        set;
    }

    public ServiceErrorType ErrorType
    {
        get;
        set;
    }

    public string ErrorMessage
    {
        get;
        set;
    }

    public T ReturnData
    {
        get;
        set;
    }
}

我使用泛型,以便每个服务都可以定义它发回的内容,标准错误标志告诉客户端应用程序发生了什么类型的错误(这些是元类型,如“内部错误”、“外部方错误”、“业务规则验证错误”),然后应用程序可以以标准方式对这些错误类型做出反应。

例如,业务错误显示在红色错误标签中,而内部错误被重定向到错误页面(在 Web 应用程序中)或关闭表单(在 Windows 应用程序中)

我最讨厌在网站上看到红色标签(我希望看到验证错误)并看到类似“数据库服务器拒绝您的连接”之类的内容,这是您仅使用字符串返回错误数据而运行的风险。

于 2010-03-27T08:25:09.693 回答
2

最好的方法是将异常包装在一些更通用的类型中并重新抛出它。所以 updateSomething() 必须声明它可以抛出某种异常(例如:UpdateFailedException),并且在 catch 块中你应该包装异常。

public String updateSomething() {
  try {
    [...]
  } catch ( SQLException e ) {
    // rollback;
    throw new UpdateFailedException(e);
  }
}

但是捕获抽象异常类型并不是一个好主意。你应该只包装那些你知道语义的东西。例如:SQLException、DataAccessException(Spring DAO)等。

如果您包装 Exception,您可以轻松包装 NullPointerException 的 InterruptedException。这可能会破坏您的应用程序。

于 2010-03-27T08:19:12.750 回答
1

像这样返回 String 有点不寻常(但也没有真正的原因)。更常用的方法是:

  • 返回一个布尔值,并有一些设置错误消息的方法,或者通过记录它,设置一些全局“最后一个错误”值,或者将一个指向错误构造的指针传递给你更新的方法;

  • 有一个 void 方法,它在失败时抛出异常,并在调用代码中处理它(如你所建议的)

我已经看到上述两种方法都被广泛使用。很难说哪个是“最好的”。尝试与您正在使用的语言的习惯用法和约定和/或您正在使用的现有代码集/库(如果有)保持一致。

于 2010-03-27T08:17:05.833 回答
0

可能最好的方法是拥有一个特定于层的自定义异常类,一旦您在特定层中捕获异常,就会将自定义异常抛出到调用层,拥有这将为您带来以下优势。

  1. 您将获得更好的模块化方法来处理异常。
  2. 当您的代码复杂性增加时,代码的维护将变得容易
  3. 您将对异常情况有更多的控制权

例如,您在业务层捕获异常并希望通知表示层

public string DummyFunction
{
   try
   {

   }
   catch(Exception ex)
   {
      throw new businessException();
   }
}
于 2013-07-28T18:52:05.920 回答