Glimpse/Glimpse — pull request #657 by edwinf (2013-11-28 05:19:02+00:00)
Title: Fix null reference exception on http custom 400

When trying to set up a new context and controller execution for a 400 error, glimpse throws a null reference exception on the data store extension. The cause is that there is no entry for the runtime policy during the new controller processing due to the exception process. This is solved by the change to the InstantiateRuntimePolicyStrategy function to verify the runtime policies existence before asking for it and falling back to the default if it does not exist.

This exposed another null reference exception in the same scenario. The TimerStrategy in this scenario would also be null, thus facilitating the change to the TryProceedWithTimer to verify that a timer was returned. This has the side effect of not tracking anything for these edge case requests. In my case, it's an error page so I'm fine with that outcome. Another option might be to load up a new timer or guarantee that the TimerStrategy always returns a valid timer.

This seems related to #336, but there are many different stack traces in that issue.

I am using the out of the box glimpse configuration for an mvc4 site on .net 4.5, with the following packages installed

Glimpse.AspNet
Glimpse.Core
Glimpse.Elmah
Glimpse.Mvc4
Glimpse.NLog

Reproduction in an mvc 4 application, add an Application_Error handler and submit a bad request (e.g. http://localhost/<)

```csharp
protected void Application_Error(object sender, EventArgs e)
{
var context = HttpContext.Current;
var exception = context.Server.GetLastError() as HttpException;
// Cannot trap 400 errors yet due to a bug in glimpse, need to fix that bug and then we can
if (exception != null && (exception is HttpRequestValidationException || exception.GetHttpCode() == 400))
{
// Have to log manually because passing the context causes the request validation exception to fire again, casue the context is bad.
Elmah.ErrorLog.GetDefault(context).Log(new Elmah.Error(exception));

context.Server.ClearError();
Response.Clear();
Response.ContentType = "text/html";
Response.ContentEncoding = Encoding.UTF8;
Response.StatusCode = (int)HttpStatusCode.BadRequest;
//Response.Write("Here");
var rd = new RouteData();
rd.Values["controller"] = "Static";
rd.Values["action"] = "InputValidation";

// can't use the old request as it's invalid, so use homepage route.
HttpRequest req = new HttpRequest("/", string.Format("{0}://{1}:{2}", Request.Url.Scheme, Request.Url.Host, Request.Url.Port),"");
var newContext = new HttpContext(req, Response);
newContext.AddError(exception);
newContext.ApplicationInstance = context.ApplicationInstance;
IController c = new StaticController();

// Will throw null reference exception in glimpse.
c.Execute(new RequestContext(new HttpContextWrapper(newContext), rd));
}
}
```