Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I handle errors in Global.asax Application_Start?

In the interest of always showing a "friendly" error page to users when they visit a site I have a catch-all at the in the Global.asax page, the majority of errors are handled by filters which seems to be the preferred method. For the most part, this works fine. However, during Application_Start, the Application_Error event (understandably) does not get triggered.

My Application_Start event contains some initialisation code which is dependent on a service call, so an easily defined point of failure is if the service is unavailable for whatever reason. The only way I've found to get around this is to do the following.

    private static Exception StartUpException;
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        Initialise();       
    }

    private void Initialise()
    {
        StartUpException = null;
        try
        {
            Bootstrapper.Initialise();
        }
        catch (Exception ex)
        {
            StartUpException = ex;
        }
    }

Then I have the following code in the Application_BeginRequest

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        if (StartUpException != null)
        {
            HandleErrorAndRedirect(StartUpException);
            HttpRuntime.UnloadAppDomain();
            Response.End();
        }
    }

This works, but seems like a bit of a hack. I'm also not sure about the consequences of calling UnloadAppDomain, or what would happen if multiple requests arrived. Is there a better way to manage this?

like image 983
DJG Avatar asked Apr 29 '13 16:04

DJG


1 Answers

We're having issues with bootstrapping in App_Start because HttpContext was not set and some of the bootstapped classes needed it; anyway this should work for your case as well:

public class MvcApplication : System.Web.HttpApplication {    
    protected void Application_BeginRequest() {
        var context = this.Context;
        FirstTimeInitializer.Init(context);
    }

    private static class FirstTimeInitializer {
        private static bool s_IsInitialized = false;
        private static Object s_SyncRoot = new Object();

        public static void Init(HttpContext context) {
            if (s_IsInitialized) {
                return;
            }

            lock (s_SyncRoot) {
                if (s_IsInitialized) {
                    return;
                }

                // bootstrap

                s_IsInitialized = true;
            }
        }
    }
}
like image 196
Ondrej Svejdar Avatar answered Nov 15 '22 04:11

Ondrej Svejdar