Reputation: 11351
I try in Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
this.Error += new EventHandler(MvcApplication_Error);
}
public void MvcApplication_Error(object sender, EventArgs e)
{
throw new NotImplementedException();
}
But the Event is never raised !
Upvotes: 2
Views: 2578
Reputation: 1795
In order to make it work you have to register the event in the MvcApplication constructor:
public MvcApplication()
{
Error += MvcApplication_Error;
}
private void MvcApplication_Error(object sender, EventArgs e)
{
//Do your stuff
}
Upvotes: 0
Reputation: 74277
The easiest way to deal with unhandled exceptions gracefully is to (A) use Elmah to hook unhandled exceptions and log them, and (B) trap the unhandled exception with the global.asax's Application_Error() method. Here's mine:
protected void Application_Error( object sender , EventArgs e )
{
// only do something special if the request is not from the local machine.
if ( !Request.IsLocal )
{
Exception exception = Server.GetLastError() ;
HttpException httpException = exception as HttpException ;
RouteData routeData = new RouteData() ;
routeData.Values.Add( "controller" , "Error" ) ;
if ( httpException != null )
{
int httpStatusCode = httpException.GetHttpCode() ;
switch ( httpStatusCode )
{
case 404 : routeData.Values.Add( "action" , "Http404FileNotFound" ) ; break ;
default : routeData.Values.Add( "action" , "HttpError" ) ; break ;
}
routeData.Values.Add( "exception" , httpException ) ;
}
else
{
routeData.Values.Add( "action" , "Http500InternalServerError" ) ;
routeData.Values.Add( "exception" , exception ) ;
}
Response.Clear() ;
Server.ClearError() ;
HttpContextBase contextWrapper = new HttpContextWrapper( Context ) ;
RequestContext newContext = new RequestContext( contextWrapper , routeData ) ;
IController errorController = new ErrorController() ;
errorController.Execute( newContext ) ;
}
return ;
}
The above method:
for local requests (e.g., the developer's machine), the exception is not handled and ASP.Net hands back the standard Yellow Screen O'Death.
handles remote requests by displaying (not redirecting -- the user sees the original URL) a friendly error page that doesn't leak implementation information (like stack traces, etc.) The logic goes like this:
If the exception can be cast to an HttpException, then the HTTP status (response) code is examined. An Http status code of 404 displays our "Resource Not Found" view, with a 404 response status; other HttpExceptions get a different "Http Error" view that sets the Response Status to 500 (Internal Server Error).
If the exception cannot be cast to an HttpException, then an "Internal Error" view is returned, which also sets the Response status to 500 (Internal Server Error).
Easy! You might want to use log4net where appropriate (say, at the point the exception is thrown) to log any contextual data that might help debug the root cause of the exception.
Upvotes: 8
Reputation: 5018
In addition to Nico's suggestion you can use an attribute on the controller such as this...
[ExceptionHandler("DefaultError", typeof(DivideByZeroException))]
public class HomeController : N2Controller
{
[ControllerAction, ExceptionHandler("Error")]
public void Index()
{
}
}
This allows you to have have more granular control (per method) of the exception handler if required or just have a single attribute in your base controller that will handle all errors.
Upvotes: 2
Reputation: 496
You can use the OnException method that is already in Controller MetaData
protected override void OnException(ExceptionContext filterContext)
{
//Build of error source.
string askerUrl = filterContext.RequestContext.HttpContext.Request.RawUrl;
Exception exToLog = filterContext.Exception;
exToLog.Source = string.Format("Source : {0} {1}Requested Path : {2} {1}", exToLog.Source, Environment.NewLine, askerUrl);
//Log the error
ExceptionLogger.Publish(exToLog, "unhandled", filterContext.RequestContext.HttpContext.Request.ServerVariables.ToString(), askerUrl);
//Redirect to error page : you must feed filterContext.Result to cancel already executing Action
filterContext.ExceptionHandled = true;
filterContext.Result = new ErrorController().ManageError(ErrorResources.GeneralErrorPageTitle, ErrorResources.GeneralErrorTitle, ErrorResources.GeneralErrorInnerBody, exToLog);
base.OnException(filterContext);
}
Upvotes: 7