Jak ustalić, czy wyjątek jest określonego typu


82

Mam kod catch:

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

W przypadku tego fragmentu kodu próbuję wstawić rekord do bazy danych: dba skonfigurował go tak, że baza danych sprawdza, czy istnieją duplikaty i zwraca błąd, jeśli są duplikaty. Obecnie jak widać dodam ten sam błąd do modelu bez względu na to jaki błąd wystąpił. Chcę, żeby to się zmieniło, więc ten błąd jest dodawany do modelu tylko wtedy, gdy został spowodowany przez zduplikowany błąd ustawiony przez dba.

Poniżej znajduje się błąd, który chcę wyłapać. Zauważ, że jest to wewnętrzny wyjątek. Czy ktoś może mi powiedzieć, jak konkretnie to złapać?

wprowadź opis obrazu tutaj


1
Zobacz odpowiedź Davide. Ogólnie rzecz biorąc, łowienie Exceptionnie jest najlepszą praktyką. Powinieneś być tak dokładny, jak to tylko możliwe i pozwolić, aby wszystko, z czym nie możesz sobie poradzić, dotarło do użytkownika / struktury.
Ryan,

Odpowiedzi:


141

przed twoim bieżącym połowem dodaj:

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

W języku C # 6 możesz wykonać następujące czynności:

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

3
czy istnieje haczyk składni „kiedy nie”?
conterio

4
@conteriocatch(DbUpdateException ex) when (!(ex.InnerException is UpdateException))
Tom

16

Zamień na System.Threading.ThreadAbortExceptionswój wyjątek.

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

Aby uzyskać nazwę wyjątku, możesz użyć

    catch (Exception exc){
       if (exc.GetType().FullName == "Your_Exception") 
       {
          // The same can be user for InnerExceptions
          // exc.InnerException.GetType().FullName
       }
   }

2
Porównywanie typu wyjątku według łańcucha jest niebezpieczne. Niefortunny błąd w pisowni uczyni wyjątek dotyczący koszmaru!
Tejas Pendse

Zgoda. Porównaj typ z typem. exc.GetType () == typeof (YourException)
Lee Oades

2

Za mało przedstawiciela do komentowania. W odpowiedzi na pytanie @conterio (w odpowiedzi @Davide Piras):

czy istnieje haczyk składni „kiedy nie”?

Jest.

catch (Exception e) when (!(e is ArgumentException)) { }

-3

Możesz rzucić okiem na klasę SQLException - i sprawdzić zawartość komunikatu o wyjątku, jeśli zawiera on to, co teraz widzisz w swoim wewnętrznym wyjątku… Coś takiego:

try
{
    //your code here
}
catch (SQLException ex)
{
    if (ex.Message.Contains("Cannot insert duplicate key in obj...."))
    {
        //your code here
    }
}

1
Wątpię, czy SqlException jest generowany bezpośrednio, ale tylko jako wyjątek wewnętrzny. Ponadto prawdopodobnie lepiej byłoby sprawdzić numer błędu niż porównywać go z treścią komunikatu.
John Saunders,

Tak, możesz również sprawdzić numer błędu. Dziękuję za komentarz.
Ann BG

Jak porównać numer błędu? Nie jestem nawet pewien, jaki to numer, ponieważ jest to naprawdę konkretny błąd?
AnonyMouse,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.