I'm enjoying my vacations, and today I was having a nice, quiet and relaxing day at home, so at some point I said "there's no better day than today to fix some ElmahR bugs" :)
During the last few weeks I have been notified about a couple of problems with ElmahR, and at the same time I've been working on ElmahR internals to introduce some mechanisms to make it more robust and to give people an easier experience when installing it. ElmahR is doing quite good when dealing with errors from other applications, but it was still missing, for example, a good way to notify about errors happening inside ElmahR itself. You know, s**t can happen in any place, right? Let's suppose, for example, that we have a problem with the database where ElmahR persists errors, if we do not handle that case the right way the risk is that external errors don't reach the connected clients, and nobody will notice them. At the same time we had no easy way to know that such a problem occurred.
In theory I could have treated ElmahR as an errors source like any other application, and have it posting errors to itself through ELMAH and the ErrorPostModule, but that way it could have been easy to trigger infinite loops of errors. I needed something more directly targeting this kind of scenario, but at the same time the basic ELMAH strategy seemed to me the way to go: an HTTP module subscribing to the application-level Error event. That works quite fine when something happens during a regular HTTP request (i.e. when an error POST arrives), but it doesn't when SignalR hubs are involved. At the time of this writing, SignalR swallows any unhandled exception coming out of a hub public method, and this makes impossible to centralize any management of unhandled errors in an HTTP module. This problem will be solved in future versions of SignalR, so I decided to handle it with a 'quick and dirty' approach while waiting for some nicer way to do it. I added some exception handling logic in every public method exposed by my main hub, and the same logic is available in an HTTP module called ErrorTrapModule, which you can add to your configuration if you want to track error during regular HTTP requests. The result of this logic is that errors happening inside ElmahR are treated like errors coming from an external app, and it is possible to associate them to a specific error feed. You will need to do 2 things to your
applicationelement inside your
elmahrsection to represent the feed of errors happening inside ElmahR
ErrorTrapModuleto your HTTP modules
The result will be something like this:
... <elmahr> ... <application name="Myself" sourceId="###ElmahR###" boxColor="boxColorElmahR" /> </elmahr> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <add name="ErrorPost" type="ElmahR.Core.ErrorTrapModule, ElmahR.Core" /> </modules> </system.webServer> ...
It should be quite straightforward, we just have to pay attention to 2 small pieces:
sourceIdvalue is a special one, its value is
###ElmahR###, and such a value allows ElmahR to understand that this is a feed for internal errors; this default value can be changed to any other string with an additional attribute to the
selfSourceId, like this:
... <elmahr selfSourceId="foo"> ... <application name="Myself" sourceId="foo" boxColor="boxColorElmahR" /> </elmahr> ...
boxColorattribute allows us to associate the box representing any feed with a specific CSS class, this way we can highlight special boxes like this one with any ad-hoc styling
This strategy is already available in the source code repository, and it works quite fine. It can be improved, I'll work on it, but it's already quite helpful. Such a system would have helped to easily spot the cause of the error happening in this first scenario.
While I was working on these problems, I also decided to follow @GregRatner advice, and now both the main solution and the sample setup zip contain an MVC source application, which will allow me to keep the testing phase more complete, and it will work as a sample for anybody wanting to monitor MVC apps with ElmahR.