Как определить, относится ли исключение к определенному типу

82

У меня есть фрагмент кода попытки перехвата:

try 
{
    ...
}
catch(Exception ex) 
{
    ModelState.AddModelError(
        "duplicateInvoiceNumberOrganisation", "The combination of organisation and invoice number must be unique");
}

Для этого фрагмента кода я пытаюсь вставить запись в базу данных: dba настроила ее так, чтобы база данных проверяла наличие дубликатов и возвращала ошибку, если дубликаты есть. В настоящее время, как вы можете видеть, я добавляю в модель одну и ту же ошибку независимо от того, какая ошибка произошла. Я хочу, чтобы это было изменено, чтобы эта ошибка добавлялась в модель только в том случае, если она была вызвана повторяющейся ошибкой, установленной dba.

Ниже приведена ошибка, которую я хочу поймать. Обратите внимание, что это внутреннее исключение. Может кто подскажет, как конкретно эту ловить?

введите описание изображения здесь

AnonyMouse
источник
1
См. Ответ Давиде. Обычно ловля Exception- не лучшая практика. Вы должны быть как можно более конкретными и позволять всему, с чем вы не можете справиться, всплывать перед пользователем / фреймворком.
Райан
1
Посмотрите этот ответ: stackoverflow.com/questions/3967140/…
Роб Паквуд,

Ответы:

141

перед вашим текущим уловом добавьте следующее:

catch(DbUpdateException ex)
{
  if(ex.InnerException is UpdateException)
  {
    // do what you want with ex.InnerException...
  }
}

С C # 6 вы можете делать следующее:

catch(DbUpdateException ex) when (ex.InnerException is UpdateException)
{
    // do what you want with ex.InnerException...
}
Давид Пирас
источник
3
есть ли уловка "когда нет" синтаксиса?
conterio
4
@conteriocatch(DbUpdateException ex) when (!(ex.InnerException is UpdateException))
Том
16

Замените System.Threading.ThreadAbortExceptionсвоим исключением.

try
{
    //assume ThreadAbortException occurs here
}
catch (Exception ex)
{
    if (ex.GetType().IsAssignableFrom(typeof(System.Threading.ThreadAbortException)))
    {
         //what you want to do when ThreadAbortException occurs         
    }
    else
    {
         //do when other exceptions occur
    }
}
Нишанта
источник
3

Чтобы получить имя исключения, вы можете использовать

    catch (Exception exc){
       if (exc.GetType().FullName == "Your_Exception") 
       {
          // The same can be user for InnerExceptions
          // exc.InnerException.GetType().FullName
       }
   }
Удай Десираджу
источник
2
Сравнение типа исключения по строке опасно. Прискорбная орфографическая ошибка превратит обработку исключений в кошмар!
Tejas Pendse
Согласовано. Сравните Тип с Типом. exc.GetType () == typeof (YourException)
Ли Оудес
2

Недостаточно репутации для комментариев. В ответ на вопрос @conterio (в ответе @Davide Piras):

есть ли уловка "когда нет" синтаксиса?

Есть.

catch (Exception e) when (!(e is ArgumentException)) { }
Джейсон
источник
-3

Вы можете взглянуть на класс SQLException - и проверить содержимое сообщения об исключении, если оно содержит то, что вы сейчас видите во внутреннем исключении… Примерно так:

try
{
    //your code here
}
catch (SQLException ex)
{
    if (ex.Message.Contains("Cannot insert duplicate key in obj...."))
    {
        //your code here
    }
}
Ann BG
источник
1
Я сомневаюсь, что SqlException вызывается напрямую, но только как внутреннее исключение. Кроме того, вероятно, было бы лучше проверить номер ошибки, чем сравнивать с текстом сообщения.
Джон Сондерс,
Да, вы также можете проверить номер ошибки. Спасибо за комментарий.
Ann BG
Как проверить номер ошибки? Я даже не уверен, что это за номер, потому что это действительно конкретная ошибка?
AnonyMouse,