2015-07-10 99 views
1

我在Windows Forms桌面应用程序上工作,该应用程序由代表对象的模型组成,这些模型表示从Web服务,业务层和UI层获取数据的对象。在这种情况下捕获异常的最佳做法

我刚刚完成的应用程序,现在我试图单元测试,并在业务层就像用try和catch错误处理所有异常:

public List<QlmResult> ReleaseBulkKeys(List<string> externalUserIdReleaseList, string activationKey) 
    { 
     try 
     { 
      List<QlmResult> qlmResultList = new List<QlmResult>(); 
      string response = string.Empty; 
      foreach (string externalId in externalUserIdReleaseList) 
      { 
       licenseAuthntication.ReleaseLicense(licenseAuthntication.DefaultWebServiceUrl, activationKey, externalId, out response); 
       qlmResultList.Add(new QlmResult { ComputerKey = externalId, Result = response }); 
      } 
      return qlmResultList; 
     } 
     catch (Exception ex) 
     { 
      string errorMsg = LoggingManager.CreateExceptionString(ex); 
      LoggingManager.SaveExceptionToLogFile(errorMsg); 
      throw; // To send Exception to UI Layer; 
     } 
    } 

现在我赶在业务层和日志异常它以一个log.txt文件,但我也想显示与异常的消息在UI用户喜欢

MessageBox.Show(ex.ToString()); 

所以我用罚球;在BL抓{}块,我把另一个try {}赶上{}到UI方式类似:

private void btnBulkRelease_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      if (currentProduct != null && currentCustomer != null) 
      { 
       QlmLicenseManager qlm = new QlmLicenseManager(currentProduct, currentCustomer, configKeys); 
       List<QlmResult> bulkResult = qlm.ReleaseBulkKeys(externalIdsLstRelease, txtReleaseActivationKey.Text); 

       foreach (var result in bulkResult) 
       { 
        MessageBox.Show(result.Result); 
       } 
      } 
      else 
      { 
       MessageBox.Show("You Should Select Customer and Product from Settings."); 
      } 
     } 
     catch(Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
     } 
    } 

我的问题:它显示在UI例外,也是在BL记录它的最佳做法,但我在BL和其他UI中使用了两个try {} catch块?

我也应该在UI中尝试使用{} catch {},或者建议仅在业务逻辑方法中使用它{?}

我想到另外两个解决方案

1-创建当有BL一个例外,这将触发对UI的事件。

2-创建一个包含两个属性的类bool exceptionDetector和字符串savedException,我会将BL Exception保存在savedException变量中,并将其发送到UI以在exceptionDetector从false更改为true时显示它。

这是一个很好的解决方案吗?

+0

解决方案2-是最合适的,但在UI中创建Exception类后,存储异常终止BL进程并在BL完成时在UI中测试Exception类。 – Graffito

+0

这不是好的方法。如果你在每种方法上编写try..catch Exception,那么你做错了。在bll中捕获豁免仅用于包装它们或添加上下文信息。使用异常处理策略来处理异常。 – sturcotte06

回答

1

如果你打算把它扔在UI层,然后在最少使用自定义异常。

眼下净你吞下不被认为是一个很好的做法

,其投射的另一个问题的例外是你不返回该工作的行和可以帮助一般例外

另一个选项是返回一个布尔成功或地位枚举作为arguement
out

我喜欢返回一个状态枚举的消息像无效的输入

1

通常我喜欢在单个函数上捕获应用程序上的所有异常。 这样,你是保护所有的代码,包括异步调用...

Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod) 

private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t) 
{ 
    //Exception handling... 
} 

注:添加Application.ThreadExceptionApplication.Run()

1

处理和传播的例外是非常昂贵的,我个人不要认为使用例外来通知用户违反业务规则是最佳做法。

在我看来,应该仅为应用程序遇到的意外问题保留异常,并且应该将事件日志和/或文件详细记录(堆栈跟踪等)。实际异常例外中提供的信息通常对最终用户无用,因此它们可能被屏蔽(即“出现意外错误,请将此情况报告给系统管理员”)。

为了提供有关业务层和客户层之间的业务规则违规和异常事件的信息,我们在每个业务层方法中使用一个错误类(错误代码加上消息)的实例作为ref参数。此实施使我们能够轻松地向客户端层中的最终用户提供特定于语言的错误消息,而无需打扰关于客户端当前正在使用的文化的信息的业务层。

相关问题