108

I have a piece of try catch code:

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

For this piece of code I'm trying to insert a record into a database: The dba has set it up so that the database checks for duplicates and returns an error if there are duplicates. Currently, as you can see, I'm adding the same error to the model no matter what error occurred. I want it changed so this error is only added to the model if it was caused by the duplicate error set up by the dba.

Below is the error I want to catch. Note it's in the inner exception. Can anyone tell me how to specifically catch this one?

enter image description here

Benjamin Gale
  • 12,977
  • 6
  • 62
  • 100
AnonyMouse
  • 18,108
  • 26
  • 79
  • 131
  • 1
    See Davide's answer. Generally catching `Exception` is not a best practice. You should be as specific as possible and let anything you can't handle bubble up to the user/framework. – Ryan Feb 14 '12 at 00:21
  • 1
    Check out this answer: http://stackoverflow.com/questions/3967140/c-sharp-entity-framework-duplicate-unique-exception – Rob Packwood Feb 14 '12 at 00:21

5 Answers5

186

before your current catch add the following:

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

From C# 6, you can do the following:

catch(DbUpdateException ex) when (ex.InnerException is UpdateException)
{
    // do what you want with ex.InnerException...
}
bojtib
  • 2,330
  • 1
  • 11
  • 14
Davide Piras
  • 43,984
  • 10
  • 98
  • 147
  • 4
    is there a catch "when not" syntax? – conterio Nov 07 '18 at 23:28
  • 8
    @conterio `catch(DbUpdateException ex) when (!(ex.InnerException is UpdateException))` – Tom Aug 07 '19 at 13:30
  • This might be helpful but unfortunately, in my case, ex.InnerException was null. What I can do is to check content of ex.Message, if there is 'timed out'-ish thing, then do something. – Moses Oct 20 '22 at 01:55
21

Replace System.Threading.ThreadAbortException with your exception.

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
    }
}
Nishantha
  • 6,065
  • 6
  • 33
  • 51
12

Not enough rep to comment. In response to @conterio question (in @Davide Piras answer):

is there a catch "when not" syntax?

There is.

catch (Exception e) when (!(e is ArgumentException)) { }
Jason
  • 349
  • 3
  • 9
8

To get name of the exception you can use

    catch (Exception exc){
       if (exc.GetType().FullName == "Your_Exception") 
       {
          // The same can be user for InnerExceptions
          // exc.InnerException.GetType().FullName
       }
   }
Uday Desiraju
  • 115
  • 1
  • 2
-3

You can take a look at the SQLException class -- and check for the contents of the exception's message if it contains what you now see in your inner exception..Something like this:

try
{
    //your code here
}
catch (SQLException ex)
{
    if (ex.Message.Contains("Cannot insert duplicate key in obj...."))
    {
        //your code here
    }
}
Ann B. G.
  • 304
  • 2
  • 6
  • 1
    I doubt that SqlException is thrown directly, but only as an inner exception. Also, it would probably be better to check the error number rather than comparing against message text. – John Saunders Feb 14 '12 at 00:44
  • Yup, you can check the error number as well. Thanks for the comment. – Ann B. G. Feb 14 '12 at 00:46
  • How do you check against the error number? I'm not even sure what's it's number is as it's a really specific error? – AnonyMouse Feb 14 '12 at 00:56