我有以下代码:
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
。
为什么SQL异常仅被通用Exception
捕获?
答案 0 :(得分: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)
将不匹配。
答案 1 :(得分: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;
}