I'm trying to implement error handling on one of our ASP.NET Web API (not core) projects (running .NET 4.7.2) to avoid running into an error in the future, that we had a couple of days ago.
The error was that this code in the Web.Config file had not been updated, but the DLL that came with the project when it was published was updated, so there was a mismatch between the versions.
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
</compilers>
</system.codedom>
The Version=2.0.1.0
in both compiler
lines were set to Version=1.0.8.0
, and the version of the DLL that was published was 2.0.1.0. This gives an error that looks like this:
Now, I would like to handle this exception in the code, and log it to our logging stack. I have searched around and found a couple of different methods of catching exceptions in a web.api project, but none of them seem to have worked. The ones I have tried are:
In the global.asax.cs
file:
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex != null)
Logger.WriteToFile(ex.Message, ex);
}
Also in the global.asax.cs
file:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = (e.ExceptionObject as Exception);
if (ex != null)
Logger.WriteToFile(ex.Message, ex);
}
In the WebApiConfig.Register
function that is automatically added to the Web.API (that handles routing setup, for example):
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Filters.Add(new GlobalExceptionFilterAttribute()); // <-- this line
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
public class GlobalExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var exceptionType = context.Exception.GetType().ToString();
var exception = context.Exception.InnerException ?? context.Exception;
try
{
if (exception != null)
Logger.WriteToFile(exception.Message, exception);
}
finally
{
base.OnException(context);
}
}
}
And in the web.config file, I added a module that should (in theory) handle the IIS level errors (taken from Catch IIS level error to handle in ASP.NET):
<system.webServer>
<modules>
<add type="ErrorHttpModule" name="ErrorHttpModule"/>
</modules>
</system.webServer>
public class ErrorHttpModule : IHttpModule
{
private HttpApplication _context;
public ErrorHttpModule() { }
public void Init(HttpApplication context)
{
_context = context;
_context.Error += new EventHandler(ErrorHandler);
}
private void ErrorHandler(object sender, EventArgs e)
{
Exception ex = _context.Server.GetLastError();
if (ex != null)
Logger.WriteToFile(ex.Message, ex);
}
public void Dispose()
{
}
}
And none of these seem to catch the error, and log it. How do I catch this error?
I have reproduced this error in a completely blank Web.API project in addition to our main project. The blank Web.API project can be found at https://github.com/Loyalar/IISExceptionCapture.