A ConfigurationErrorsException was being thrown from within a class library linked to an ASP.NET site. The site logs all errors using the Global.ASAX error event and by overridding the ASP.NET page OnError() protected method. Neither of which handled the ConfigurationErrorsException when it was thrown.
When the type of exception in the class library was changed from ConfigurationErrorsException to ApplicationException, the page OnError method handles the exception.
Why does the type of the Exception thrown change the way ASP.NET handles the exception? If you want all errors to be handled in the ASP.NET OnError and/or Global.asax page Error event which Exceptions are safe to throw?
The following code demonstrates what I've described. A breakpoint in the OnError will get hit when you click the App Exception button but not when you click the Configurations Exception button...
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="OnErrorTest.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnInvalidOpEx" runat="server" Text="Invalid OP Exception" OnClick="btnInvalidOpEx_OnClick" />
<asp:Button ID="btnAppEx" runat="server" Text="Application Exception" OnClick="bthnAppEx_OnClick" />
<asp:Button ID="btnConfigEx" runat="server" Text="Configurations Exception" OnClick="btnConfigEx_OnClick" />
</div>
</form>
</body>
</html>
Code behind
using System;
using System.Configuration;
using System.Web;
namespace OnErrorTest
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnError(EventArgs e)
{
HttpContext ctx = HttpContext.Current;
System.Exception exception = ctx.Server.GetLastError();
}
protected void bthnAppEx_OnClick(object sender, EventArgs e)
{
throw new ApplicationException("Application Error");
}
protected void btnConfigEx_OnClick(object sender, EventArgs e)
{
throw new ConfigurationErrorsException("Configurations Error");
}
protected void btnInvalidOpEx_OnClick(object sender, EventArgs e)
{
throw new InvalidOperationException("Configurations Error");
}
}
}
EDIT: It was suggested that ConfigurationErrorsException is a system exception and it's meant to be thrown by the .NET Framework and not an application. It does indeed derive from SystemException, however so does InvalidOperationException. OnError catches InvalidOperationException
CONCLUSION: Don't throw anything derived from ConfigurationException unless your intent is that it's not to be processed in either the OnError method of an ASP.NET Page or global exception handlers. I've tested MVC and no Controller.OnException has no such discrimination against ConfigurationException.