在这种情况下捕获异常的最佳实践是什么?

本文关键字:是什么 最佳 这种情况下 捕获异常 | 更新日期: 2023-09-27 18:02:19

我的工作是Windows窗体桌面应用程序,由代表对象的模型组成,从web服务,业务层和UI层获取数据。

我刚刚完成了应用程序,现在我试着对它进行单元测试,并通过尝试捕获业务层中的错误来处理所有异常,如下所示:

    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());

所以我使用了throw;在BL catch{}块中,我把另一个try {} catch{}放到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中记录它,但我使用两个try {} catch块一个在BL中,另一个在UI中,这是最佳实践吗?

我也应该在UI中使用try {} catch{}还是建议只在业务逻辑方法中使用它?

我想到了另外两个解决方案

1-创建一个事件,当BL中出现异常时触发UI。

2-创建一个类,包含两个属性bool exceptionDetector和string savedException,我将保存BL Exception在savedException变量,并将其发送到UI,以显示当exceptionDetector从false变为true。

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

在这种情况下捕获异常的最佳实践是什么?

如果你打算将它抛出到UI层,那么至少使用自定义Exception。

现在在网络中,你正在吞下一个一般的例外
这不是一个好的做法

抛出异常的另一个问题是你没有返回工作的行,这可能是有帮助的。

另一个选项是返回bool成功或状态枚举作为参数

我喜欢为无效输入

这样的消息返回状态枚举

通常我喜欢在一个函数上捕获应用程序中的所有异常。这样,您可以保护所有代码,包括异步调用…

Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod)
private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t)
{
    //Exception handling...
}

注:Application.Run()前加Application.ThreadException

处理和传播异常是非常昂贵的,我个人认为使用异常通知用户违反业务规则不是最佳实践。

在我看来,异常应该仅用于应用程序遇到的未预料到的问题,并且应该详细记录(堆栈跟踪等)到事件日志和/或文件中。在实际异常异常中提供的信息通常对最终用户来说是无用的,因此它们可能应该被屏蔽(即。"发生意外错误,请向系统管理员报告")。

为了提供业务层和客户端层之间业务规则违反和异常发生的信息,我们在每个业务层方法中使用一个错误类的实例(错误代码加消息)作为ref参数。这种实现使我们能够在客户端层中轻松地向最终用户提供特定于语言的错误消息,而不必向业务层提供有关客户端当前操作所在文化的信息。