在c#中捕获特定异常和一般异常 [英] Catching specific vs. generic exceptions in c#

查看:159
本文介绍了在c#中捕获特定异常和一般异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题来自于一个针对我创建的对象的代码分析。分析说,我应该捕获一个更具体的异常类型,而不只是基本的异常。

This question comes from a code analysis run against an object I've created. The analysis says that I should catch a more specific exception type than just the basic Exception.

你发现自己只使用捕获通用异常或试图捕获一个特定的异常并默认使用多个catch块的通用异常?

Do you find yourself using just catching the generic Exception or attempting to catch a specific Exception and defaulting to a generic Exception using multiple catch blocks?

有问题的代码块之一如下:

One of the code chunks in question is below:

internal static bool ClearFlags(string connectionString, Guid ID)
{
    bool returnValue = false;
    SqlConnection dbEngine = new SqlConnection(connectionString);
    SqlCommand dbCmd = new SqlCommand("ClearFlags", dbEngine);
    SqlDataAdapter dataAdapter = new SqlDataAdapter(dbCmd);

    dbCmd.CommandType = CommandType.StoredProcedure;
    try
    {
        dbCmd.Parameters.AddWithValue("@ID", ID.ToString());

        dbEngine.Open();
        dbCmd.ExecuteNonQuery();
        dbEngine.Close();

        returnValue = true;
    }
    catch (Exception ex)
    { ErrorHandler(ex); }

    return returnValue;
}

感谢您的建议

EDIT:这是代码分析的警告

警告351 CA1031:Microsoft.Design:Modify'ClearFlags Guid)'捕获比'Exception'更具体的异常或重新抛出异常

Warning 351 CA1031 : Microsoft.Design : Modify 'ClearFlags(string, Guid)' to catch a more specific exception than 'Exception' or rethrow the exception

推荐答案

异常。

在大多数情况下,你应该抓住并处理最具体的异常,只有当你能用它做一些有用的事情。

In most cases you should catch and handle the most specific exception possible and only if there is something useful you can do with it.

异常(haha),如果你正在捕获日志记录并重新抛出异常,那么有时可以捕获顶级异常,记录它并重新抛出异常。

The exception (haha) to this is if you are catching for logging and re-throw the exception, then it is sometimes OK to catch a top level Exception, log it and rethrow it.

你几乎从来不会捕获顶级异常并吞下它。这是因为如果你正在捕获一个顶级异常,你真的不知道你在处理什么;绝对任何东西都可能导致它,所以你几乎肯定不能做任何事情,将处理每一个失败的情况下正确。可能有一些失败,你可能只想沉默地处理和吞咽,但通过吞咽顶级异常,你也将吞下一大堆,真的应该被抛出你的代码来处理更高的。在你的代码示例中,你可能想要做的是处理SQLException和log + swallow;然后对于异常,记录并重新抛出它。这覆盖了你自己。你仍然记录所有的异常类型,但你只吞咽一个相当可预测的SQLException,表明你的SQL /数据库有问题。

You should almost never catch a top level Exception and swallow it. This is because if you are catching a top level exception you don't really know what you are handling; absolutly anything could have caused it so you will almost certainly not be able to do anything that will handle every single failure case correctly. There probably are some failures that you may just want to silently handle and swallow, but by just swallowing top level Exceptions you'll also be swallowing a whole bunch that really should have been thrown upwards for your code to handle higher up. In your code example what you probably want to do is handle a SQLException and log+swallow that; and then for an Exception, log and rethrow it. This covers yourself. You're still logging all exception types, but your only swallowing the fairly predictable SQLException which indicates problems with your SQL/database.

一个常见的做法是只有每个句柄你实际上可以解决在那一点,如果你不能解决它在代码中的那一点,那么你允许它向上冒泡。如果你无法在下一级解决它,请允许它继续。如果它到达未处理的顶部,然后向用户显示礼貌的方式(可能尝试快速自动保存),并关闭应用程序。通常情况下,允许应用程序在未处理的异常之后继续运行是更糟的,因为您无法预测应用程序的状态,因为异常已经发生。最好只是关闭并重新启动应用程序以恢复到预期的状态。

A common practise is to only every handle exceptions that you can actually resolve at that point, if you can't resolve it at that point in code then you allow it to bubble upwards. If you can't resolve it at the next level up, allow it to continue up. If it reaches the top unhandled then display a polite appology to the user (perhaps attempt a quick autosave) and close the app. It's generally considered worse to allow an app to continue running after an unhandled exception because you can't predict the state of the application as something exceptional has occured. It's better just to shutdown and restart the app to get back to an expected state.

这篇关于在c#中捕获特定异常和一般异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆