为什么try / catch SqlException没有捕获SqlException类型的异常?

问题描述 投票:-1回答:2

我有以下代码:

    try
    {
        Data.CreateUserAndAccount.ExecuteProcedure(accountName, firstName, lastName, email, password);
        return String.Empty;
    }
    catch (SqlException databaseError)
    {
        string result = IdentifyError(databaseError);
        return result;
    }
    catch  (Exception)
    {
        throw;
    }

我故意通过违反唯一密钥来抛出SQL异常。然而,例外是由Exception而不是SqlException捕获的。当我检查InnerException细节时,例外是System.Data.SqlClient.SqlException类型。

InnerException Details

为什么SQL异常只被通用Exception捕获?

c# try-catch sqlexception
2个回答
4
投票

问题是你试图捕获SqlException,但这不是异常类型:它是InnerException。

如果user10954641是正确的,它的UpdateException,你可以简单地抓住:

try
{
}
catch (UpdateException e)
{
}

如果它是一个不同的异常,那么捕获实际抛出的任何异常类型。或者,您可以有条件地捕获InnerException为SqlException的异常:

try
{
}
catch (Exception e) when (e.InnerException is SqlException)
{
}

如果您想知道为什么catch (SqlException)不起作用,请考虑以下代码:

public void ThrowException()
{
    try
    {
        MakeDatabaseCall();
    }
    catch (Exception e)
    {
        throw new Exception("Uh oh!", e);
    }
}

public void MakeDatabaseCall()
{
    throw new SqlException();
}

ThrowException()的调用最终会产生MakeDatabaseCall()的错误,但异常类型不会是SqlException,因为我们将它包装在另一个异常中(在这种情况下是异常基类):Exception。但是,因为我们将MakeDatabaseCall()抛出的异常传递给构造函数,我们的“呃哦!”异常将在其SqlException字段中包含InnerException

当你使用try / catch(ExceptionType e)时,你指示.NET在决定输入哪个catch语句之前模式匹配异常。为了便于说明,下面的两段代码大致相同:

try
{
}
catch(SqlException e)
{
    //catches an SqlException
}

try
{
}
catch(Exception e) when (e is SqlException)
{
    //catches an SqlException
}

显然,在我们的ThrowException例子中,Exception不是来自SqlException,所以catch (SqlException e)不会匹配。


0
投票

事实证明,EntityCommandExecutionException类型的例外是从DataException派生的。

我原本打算在SqlException.Number上执行一些逻辑,这就是为什么我试图抓住SqlException

但是,要解决这个问题,请抓住DataException,然后将InnerException投射到SqlException

try
{
    Data.CreateUserAndAccount.ExecuteProcedure(accountName, firstName, lastName, email, password);
    return String.Empty;
}
catch (DataException procedureError)
{
    SqlException sqlError = (SqlException)procedureError.InnerException;
    string result = IdentifyError(sqlError);
    return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.