C# 是否尝试捕获每个数据库连接?

C# 是否尝试捕获每个数据库连接?,c#,.net,error-handling,try-catch,C#,.net,Error Handling,Try Catch,是否建议在打开DB连接的每个函数中放置一个try-catch块,并在其中记录错误,还是应该在应用程序的更高层捕获错误 public static Category GetCategoryByName(string name) { Category result; try { using (IDbConnection conn = ConnectionHelper.CreateDbConnectionByName(_connectionStringName)

是否建议在打开DB连接的每个函数中放置一个try-catch块,并在其中记录错误,还是应该在应用程序的更高层捕获错误

public static Category GetCategoryByName(string name)
{
    Category result;
    try
    {
        using (IDbConnection conn = ConnectionHelper.CreateDbConnectionByName(_connectionStringName))
        {
            conn.Open();
            using (IDbCommand cmd = conn.CreateCommand())
            {
                //do stuff
            }
        }
    }
    catch(Exception e)
    {
         // log error here?
    }
    return result;
}
或者更确切地说

try
{
    Category myCat = DataTools.GetCategoryByName("myCat");
    // other stuff
}
catch(Exception e)
{
   // log error here?
}

总而言之:应该尽早在代码中捕获错误吗?或者我应该在我有更多上下文信息的地方捕捉它们吗?

这取决于情况,但一般来说,只有在您可以对异常采取措施,或者您有特定代码(例如重试)时,才捕捉异常,否则,让异常冒泡出来,最顶层可以集中记录/处理异常


任何其他方法都会导致大量日志代码散布在所有业务逻辑中。

我更喜欢第一种方法,但您仍然需要确定在捕获块中还需要做什么

  • 重新显示异常
  • 是否引发另一个(更一般的)异常
  • 是否将null返回给调用方

我通常只处理UI中的异常,下面的所有内容我都会将其返回到顶层。通过这种方式,堆栈跟踪一直保持不变。你可以随时记录并扔掉它

我以前也用过这个:


尝试
{
DB命令
}
捕获(例外情况除外)
{
日志(ex)
抛出;//保留堆栈跟踪
}

捕获异常时,始终尽量使用最准确的异常。例如,在使用SQL Server时,捕获SqlException,因为它将包含比一般异常多得多的有关异常的信息。您可以获得实际的行号和其他有用的诊断信息

提取并记录所有相关内容后,重新显示异常或将其包装为不太特定的异常,如InvalidDataException或exception,然后抛出该异常。然后,您可以在更高的级别捕获这些更通用的异常

try
{
    // Execute DB call here
}
catch(SqlException exp)
{
    // Log what you need from here.
    throw new InvalidOperationException("Data could not be read", exp);
}
当您从更高级别调用此方法时,只需捕获InvalidOperationException。如果更高级别确实需要更多细节,InnerException将提供可以访问的SqlException

我所遵循的异常处理的一般方法是只捕获我可以有效执行的操作。在较低级别的代码中捕获真正的一般异常没有意义,因为您确实可以预期一切都会出错,或者能够从每个异常中恢复,例如OutOfMemoryException或StackOverflowException

try
{
    // Execute DB call here
}
catch(SqlException exp)
{
    // Log what you need from here.
    throw new InvalidOperationException("Data could not be read", exp);
}