2

In my ASP.NET MVC 3 application, I use EF 4.2. In my database, I have a unique constraint for a column.

I try to insert same data in order to see what I get but I am getting the below error:

An error occurred while updating the entries. See the inner exception for details.

Inside the inner exception I can see the full error about unique constraint. But how can I uniquely catch this exception to tell the user this:

You are entering the same value again.

Here is what I do currently:

try
{
    UpdateModel<ConditionType>(conditionType, null, null, new string[] { "ConditionTypeId" });
    _conditionTypeRepository.Save();

    return RedirectToAction("conditiontype");
}
catch (Exception ex)
{
    ModelState.AddModelError("", "There was an error while updating: " + ex.Message);
}

But this is a generic approach. What I would like to do is to provide a specific message.

Any thoughts?

Edit:

I tired the below but this time it didn't catch it:

catch (SqlException ex)
{
    if (ex.Number == 2627)
    {
        ModelState.AddModelError("", "You are entering the same value again.");
    }

    ModelState.AddModelError("", "There was an error while updating the value: " + ex.Message);
}

I dug into a little bit and it turned out that it throws an exception type of System.Data.Entity.Infrastructure.DbUpdateException which does not contain the exception number.

EDIT:

Here how I solve the problem but I am sure it is not the best way of solving it. Any idea how to refactor this code?

catch (Exception ex) {

    if (ex.InnerException.InnerException.GetType() == typeof(SqlException)) {

        if (((SqlException)ex.InnerException.InnerException).Number == 2627)
            ModelState.AddModelError("", "You are entering the same value again.");
        else
            ModelState.AddModelError("", "There was an error while updating the value: " + ex.Message);

    } else {
        ModelState.AddModelError("", "There was an error while updating the value: " + ex.Message);
    }
}
6
  • 1
    In the debug-window click the plus sign, and you'll see the inner exception that occured. Commented Dec 27, 2011 at 13:38
  • 1
    Something similar was already discussed. See if this can help you stackoverflow.com/questions/3694359/… Commented Dec 27, 2011 at 13:40
  • @LasseEdsvik ok, I will tell the end user to do that. did you read the question carefully? Commented Dec 27, 2011 at 13:41
  • @JQone I looked at it now. Can you see my update on the question. Commented Dec 27, 2011 at 13:49
  • @JQone the main problem is that it does not catch SqlException. If I try to catch it, it throws the unhanded exception. Commented Dec 27, 2011 at 14:02

3 Answers 3

3

You could do something like this to look for an inner exception that is a SqlException and then handle the sql exception differently.

catch(Exception ex)
{
    Exception current = ex;
    SqlException se = null;
    do
    {
        se = current.InnerException as SqlException;
        current = current.InnerException;
    }
    while (current != null && se == null);

    if (se != null)
    {
        // Do your SqlException processing here
    }
    else
    {
        // Do other exception processing here
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

This will not do because the code does not descend to the InnerExceptions.
@Designpattern - Good catch. My intention was to walk it (thus the while ex.Inner != null), just forgot to actually update the variable.
1

One could also use the GetBaseException() method as that would get you the root cause exception which is the SqlException.

Comments

0

To get the innermost Exception, you could do something like this:

SqlException se = null;
Exception next = ex;

while (next.InnerException != null) 
{
   se = next.InnerException as SqlException;
   next = next.InnerException;
}

if (se != null)
{
    // Do your SqlException processing here
}
else
{
    // Do other exception processing here
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.