Search code examples
c#asp.netentity-frameworkexceptionusing

How can I automatically throw an ApplicationException if a database connection fails inside of a using statement instantiating a DbContext resource?


EDIT, read first: It's not the using statement eating my ApplicationException, it's the DependencyResolver I was using in my real code. I didn't even think to look there at first, but sure enough, if I try to instantiate the class directly (the same way I did in my simplified sample code below) it works as expected. It only behaves the way I documented below if I use the DependencyResolver in the using statement. I simply didn't think to mention this in my question because I overlooked it. I'm using a Unity container, just FYI. I'll update this as I work through it and might just delete it.

Update 2: Ok so it turns out that returning a null resource when a service location throws an exception is a completely normal and expected behavior inside MVC. I just went completely blind to the fact that I was using the dependency injection when I first encountered this behavior and confused myself. So I'll leave this question up in case anybody else ever finds themselves in a similar situation. You can't throw an exception when creating a resource that is resolved with the DependencyResolver service locator! It will swallow the exception and return a null resource!

Also in case anybody is wondering what I changed in light of this new information: I simply moved my database checking/exception throwing logic inside of a few key methods within the repository instead of within the constructor. I also stopped using Unity and switched to Ninject, and went from a service locator pattern to having my container wrapped in a singleton class, but this had nothing to do with the problem I encountered that lead to this thread and was more of just a stylistic choice.

End edits

So lets say I have some kind of class that accesses a database, like this...

public class Foo : IDisposable {

    private DbContext db = new FooDbContext();

    public DoSomething(){
        // do something with the FooDbContext...
    }

    // Dispose is implemented here as well...

}

When I go to use that class, I access it like this...

using (Foo foo = new Foo()){
    foo.DoSomething();
}

So what I want to accomplish is that whenever a Foo class is constructed, if the underlying DbContext can not establish a connection, an ApplicationException is thrown.

So I add the following constructor to the Foo class...

public Foo() {
    try
        {
            db.Database.Connection.Open();
        }
        catch
        {
            throw new ApplicationException("Database is not currently available. Try again later.");
        }
}

but here's the problem, going back to this code...

using (Foo foo = new Foo()){
    foo.DoSomething();
}

When that using statement is executed while the database is unavailable (and I've confirmed this via debugging) an ApplicationException is thrown when Foo is constructed, however, that ApplicationException is ignored, and the DoSomething method is invoked anyway. At that point, what I get is a NullReferenceException instead of my desired ApplicationException because foo is null.

What happened to my ApplicationException? Why is it being ignored? And what can I do to make sure the ApplicationException bubbles up?

I don't actually want to handle the ApplicationException. For some context, this is an ASP.NET MVC application. I want the ApplicationException to go unhandled, and let the custom error page I set up display the message contained in the ApplicationException to the user.


Solution

  • I think that your issue without going in db and connection details is something because of the using block, the using block swallow the exception happen in the constructor.

    http://www.digitallycreated.net/Blog/51/c%23-using-blocks-can-swallow-exceptions

    https://msdn.microsoft.com/en-us/library/aa355056.aspx