Проблема в том, что вы пытаетесь поймать 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)
не будет совпадать.