0

I have the following code in a library to perform a delete operation on database records. My code uses the Dapper library. The error is happening when I call the Dapper Execute() method.

Some of the database table records can not be deleted because they are referenced by related records in other tables. When a record can't be deleted, the database error "The DELETE statement conflicted with the REFERENCE constraint" happens (as expected). This error causes a System.Data.SqlClient.SqlException when calling Execute, and this exception crashes my program.

I wrote a try/catch to handle this error, but the program still crashes in the try and doesn't move to the catch block. It seems that maybe Execute() doesn't throw the exception? I've also tried using the Query() method with the same outcome. I am at a loss as to how I can catch and deal with this exception!

private IDbConnection db;

public Repository(string connectionString)
{
    db = new SqlConnection(connectionString);
}

public void DeletePerson(string PersonID)
{
    string query = "DELETE FROM PERSON WHERE PersonID = @PersonID";

    try
    {
        db.Execute(query, new { PersonID });  //program crashes here b/c of SqlException
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

Here is the code that calls this method (from a different project). It is also in a try/catch, but the catch is never reached.

string id = "BELWIT";
try
{
    conn.DeletePerson(id);
}
catch
{
    MessageDialog errorMsg = new MessageDialog("Delete failed.");
    errorMsg.ShowAsync();
}
Some Girl
  • 43
  • 6
  • The behavior you're reporting isn't _normal_, which makes me think there's something specific about your _context_ that might point to the root cause. For example, several people have reported similar issues [when using Oracle](https://stackoverflow.com/questions/51695314/console-application-crashing-not-executing-global-try-catch-and-unhandledexcept) or [Oracle's MySql Adapter](https://stackoverflow.com/questions/60021282/c-sharp-dapper-mysql-random-error-i-e-fatal-error-reading-from-the-stream-h). Is there any context you can provide about your app that might be relevant? – StriplingWarrior Mar 25 '22 at 19:21
  • You're completely right, it was my own Exception Settings in Visual Studio which were causing my application to break. I posted an answer with more info about this in case it helps anyone else in the future. – Some Girl Mar 25 '22 at 19:49
  • 1
    You should avoid doing `catch (Exception ex) { throw ex; }` as doing so destroys the stack trace. If you can't actually handle the exception, don't catch it. The result will be the same, but you'll maintain the entire stack trace. – Daniel Mann Mar 25 '22 at 19:56
  • Thanks for the tip! What should I do to make it better? Remove the entire try/catch block from the DeletePerson method? – Some Girl Mar 25 '22 at 20:02
  • If you're not going to respond to the exception in some way, then just remove the try/catch. If you want to include additional information along with the exception, use `throw new Exception($"...", ex);`. If you want to do something (e.g. logging), but re-throw the same exception (this should be rare), use `throw;` instead of `throw ex;`. – StriplingWarrior Mar 25 '22 at 21:30
  • Thank you. To clarify, if what I want to do is just send the exception along to the location that called DeletePerson (so that the MessageDialog can appear), then I just use `throw;` – Some Girl Mar 25 '22 at 21:54

2 Answers2

3

It looks like this error was actually caused by my Visual Studio settings.

There was a checkbox in Exception Settings where 'Break When Thrown' was checked for System.Data.SqlClient.SqlException. So it was breaking and stopping execution in Visual Studio. Ignoring the exception popup and clicking 'Continue' allowed my code to move on to the catch block.

Dumb outcome and considered deleting, but maybe leaving it here in case anyone else experiences the same issue could be helpful?

Some Girl
  • 43
  • 6
0

It seems like errorMsg.ShowAsync() is an async method. One possibility is that you are not awaiting that method, so the program finishes execution before it can show that message. Can you try changing it to

await errorMsg.ShowAsync();

You'll also need to mark whatever method is calling that as async.

  • That line of code is never reached, since the app crashes on the db.Execute line. The program still crashes, even if I remove the MessageDialog completely and try to put the 'Delete failed' message out to a TextBlock or something. – Some Girl Mar 25 '22 at 18:46