Recently I had a bug in one of my website because of a recursive infinite loop. The effect was some random restart of IIS but noting in the sitecore logs and not way to know why.
In the windows event viewer I saw in the IIS section that the I had some IIS crashes with the event code 5011.
After googling a little bit I found this website:
http://martinnormark.com/how-to-handle-iis-event-id-1009-event-id-5011-on-iis-7
So, if you create a dll with this class
#region Using
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Web;
#endregion
/// <summary>
/// Handles all unhandled exceptions from in the current AppDomain.
///
/// Works great to catch unhandled exceptions thrown by IIS's child threads, /// which will make the application pool terminate unexpectedly
/// without logging. This makes sure your Exception /// is logged to the Application event log.
/// </summary>
public class UnhandledExceptionModule : IHttpModule
{
#region Fields
private static int _UnhandledExceptionCount = 0;
private static string _SourceName = null;
private static object _InitLock = new object();
private static bool _Initialized = false;
#endregion
#region IHttpModule members
public void Init(HttpApplication app)
{
// Do this one time for each AppDomain.
if (!_Initialized)
{
lock (_InitLock)
{
if (!_Initialized)
{
string webenginePath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "webengine.dll");
if (!File.Exists(webenginePath))
{
throw new Exception(String.Format(CultureInfo.InvariantCulture, "Failed to locate webengine.dll at '{0}'. This module requires .NET Framework 2.0.", webenginePath));
}
FileVersionInfo ver = FileVersionInfo.GetVersionInfo(webenginePath);
_SourceName = string.Format(CultureInfo.InvariantCulture, "ASP.NET {0}.{1}.{2}.0", ver.FileMajorPart, ver.FileMinorPart, ver.FileBuildPart);
if (!EventLog.SourceExists(_SourceName))
{
throw new Exception(String.Format(CultureInfo.InvariantCulture, "There is no EventLog source named '{0}'. This module requires .NET Framework 2.0.", _SourceName));
}
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException);
_Initialized = true;
}
}
}
}
public void Dispose()
{
}
#endregion
#region UnhandledException event handler
public void OnUnhandledException(object o, UnhandledExceptionEventArgs e)
{
// Let this occur one time for each AppDomain.
if (Interlocked.Exchange(ref _UnhandledExceptionCount, 1) != 0)
return;
StringBuilder message = new StringBuilder("\r\n\r\nUnhandledException logged by UnhandledExceptionModule:\r\n\r\nappId=");
string appId = (string)AppDomain.CurrentDomain.GetData(".appId");
if (appId != null)
{
message.Append(appId);
}
Exception currentException = null;
for (currentException = (Exception)e.ExceptionObject; currentException != null; currentException = currentException.InnerException)
{
message.AppendFormat("\r\n\r\ntype={0}\r\n\r\nmessage={1}\r\n\r\nstack=\r\n{2}\r\n\r\n",
currentException.GetType().FullName,
currentException.Message,
currentException.StackTrace);
}
EventLog Log = new EventLog();
Log.Source = _SourceName;
Log.WriteEntry(message.ToString(), EventLogEntryType.Error);
}
#endregion
}
Add add this
<httpmodules>
<add name="UnhandledExceptionModule" type="UnhandledExceptionModule"/>
.....
</httpmodules>
You will have more details about the cause of this error a StackOverflowException in my case.
It takes me a lot of time to find why because I didn't find how to know witch line or class cause the exception but it already help a lot :)
This class also adds all the unhandled error in the event viewer so it is also great to have it.