Is there any way to log an exception and handle it? If I catch an exception, but don't want to leave it unhandled, i'd like to still log it in the Errors table. Can this be done easily?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
try
{
throw new NotImplementedException();
}
catch (Exception e)
{
foreach (var filter in GlobalFilters.Filters)
{
if (filter.Instance is ErrorLogFilter)
{
var f = filter.Instance as ErrorLogFilter;
f.OnException(new ExceptionContext(ControllerContext, e));
}
}
}
I actually took this one step further and created a .Log() extension method on Exception.
public static class ExceptionExtensions
{
public static void Log(this Exception theException, ControllerContext theContext)
{
foreach (var filter in GlobalFilters.Filters)
{
if (filter.Instance is ErrorLogFilter)
{
var f = filter.Instance as ErrorLogFilter;
f.OnException(new ExceptionContext(theContext, theException));
}
}
}
}
Thanks Erik. It's a nice solution, however, simply re-throwing the exception would notify ELFAR of the exception. I've written a blog post on the subject.
Last edit: Steven Bey 2012-05-11
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Very nice solution, but is it possible to log exceptions without having ControllerContext, for example in different console project ?
I'd like to use sth like that:
public static void Log(this Exception theException)
{
foreach (var filter in GlobalFilters.Filters)
{
if (filter.Instance is ErrorLogFilter)
{
var f = filter.Instance as ErrorLogFilter;
f.OnException(new ExceptionContext(new ControllerContext(), theException));
// f.OnException(new ExceptionContext(null, theException));
// var context = new ExceptionContext();
// context.Exception = theException;
// f.OnException(context);
}
}
}
but without success. Everytime I got an error: "The method or operation is not implemented." or "Value cannot be null. Parameter name: controller" or "Object reference not set to an instance of an object."
Can somebody help me ?
Thanks in advance:
Marcin
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Rethrowing the exception will result in an unhandle exception propogating to the client, essentially resulting in a YSOD or 500 Internal Server Error. The whole point is to handle th exception, but log it so it can be investigated. I find this particularly useful with exceptions for external resources (Web requests, file access, etc..). There is no point in passing this on to the user if you can continue.
Also, I read your blog and I think you should just use throw, rather than throw e. If you use throw e it will lose the stack trace.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I see your point. I've updated the blog post to include your comment but have left both solutions, so that people can us one or the other in the appropriate situation.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In MVC I'm not always handling exceptions in Controller. Sometimes I'm doing it in service layer etc. where ControllerContext is not accessible (if you will not pass it as a parameter). So I wrote additional extension method:
public static void LogFromContext(this Exception theException)
{
foreach (var filter in GlobalFilters.Filters)
{
if (filter.Instance is ErrorLogFilter)
{
var f = filter.Instance as ErrorLogFilter;
var fieldInfo = f.GetType().GetField("provider", BindingFlags.NonPublic | BindingFlags.Instance);
var provider = (IErrorLogProvider)fieldInfo.GetValue(f);
var context = HttpContext.Current;
var error = new ErrorLog(provider.Application, theException);
if (context != null)
{
error.User = context.User != null ? context.User.Identity.Name : string.Empty;
error.ServerVariables.Add(context.Request.ServerVariables);
error.QueryString.Add(context.Request.QueryString);
error.Form.Add(context.Request.Form);
error.Cookies.Add(context.Request.Cookies);
}
provider.Save(error);
}
}
}
Hope that will going to help someone
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Is there any way to log an exception and handle it? If I catch an exception, but don't want to leave it unhandled, i'd like to still log it in the Errors table. Can this be done easily?
FYI, I found a solution that works pretty well.
I actually took this one step further and created a .Log() extension method on Exception.
Then you just need to use it as such:
Last edit: Erik Funkenbusch 2012-05-10
Thanks Erik. It's a nice solution, however, simply re-throwing the exception would notify ELFAR of the exception. I've written a blog post on the subject.
Last edit: Steven Bey 2012-05-11
Very nice solution, but is it possible to log exceptions without having ControllerContext, for example in different console project ?
I'd like to use sth like that:
public static void Log(this Exception theException)
{
foreach (var filter in GlobalFilters.Filters)
{
if (filter.Instance is ErrorLogFilter)
{
var f = filter.Instance as ErrorLogFilter;
f.OnException(new ExceptionContext(new ControllerContext(), theException));
// f.OnException(new ExceptionContext(null, theException));
but without success. Everytime I got an error: "The method or operation is not implemented." or "Value cannot be null. Parameter name: controller" or "Object reference not set to an instance of an object."
Can somebody help me ?
Thanks in advance:
Marcin
Rethrowing the exception will result in an unhandle exception propogating to the client, essentially resulting in a YSOD or 500 Internal Server Error. The whole point is to handle th exception, but log it so it can be investigated. I find this particularly useful with exceptions for external resources (Web requests, file access, etc..). There is no point in passing this on to the user if you can continue.
Also, I read your blog and I think you should just use throw, rather than throw e. If you use throw e it will lose the stack trace.
I see your point. I've updated the blog post to include your comment but have left both solutions, so that people can us one or the other in the appropriate situation.
In MVC I'm not always handling exceptions in Controller. Sometimes I'm doing it in service layer etc. where ControllerContext is not accessible (if you will not pass it as a parameter). So I wrote additional extension method:
Hope that will going to help someone