Як визначити, чи є виняток певного типу


82

У мене є шматок коду спроби лову:

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

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

Нижче наведена помилка, яку я хочу вловити. Зверніть увагу, що це у внутрішньому винятку. Хтось може сказати мені, як конкретно зловити цього?

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


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)
Lee Oades

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
    }
}

1
Я сумніваюся, що SqlException кидається безпосередньо, але лише як внутрішній виняток. Крім того, можливо, було б краще перевірити номер помилки, а не порівнювати з текстом повідомлення.
Джон Сондерс

Так, ви також можете перевірити номер помилки. Дякую за коментар.
Ann BG

Як перевірити номер помилки? Я навіть не впевнений, що це номер, оскільки це дійсно конкретна помилка?
AnonymousMouse
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.