My boss once told me, “Good programming is good Error Handling”. No user enjoys the infamous YSOD(Yellow Screen of Death). It’s just ugly, and shows a general lack of concern over your code if it occurs in a production environment!
However, let’s face it…Bug’s happen. Sometimes there’s nothing you can do about it, others you can. Either way, the End-User should never see the YSOD.
Fortunately in MVC3, there is a built in piece of functionality that comes standard when you create a new MVC project.
It’s called the HandleErrorAttribute, and it can be applied in two different ways. First off is the method by method or class by class way of doing it.
// Use it here
[HandleError]
public class HomeController : Controller
{
// Or here
// [HandleError]
public ActionResult Index()
{
return View();
}
}
The other way is by utilizing the Global Filters of MVC3. This comes default in a new MVC3 project, and is located in the Global.asax file.
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
The part of this to note is the filters.Add(new HandleErrorAttribute()); This turns on error handling for every controller in your app.
Please Note: It will only handle 500 errors, so 404’s need to be handled differently. I’ll get to that shortly.
The next step in the process is to turn on customErrors in the web.config file at the root of the web app, (NOT the one in the /views folder).
Find <system.web> in your web.config, and then put this in there…
<customerrors mode="On" defaultredirect="~/Error/HttpError">
<error redirect="~/Error/NotFound" statuscode="404" />
</customerrors>
The defaultredirect allows you to have somewhere to go in case your error page errors, and the error allows you to have different places to go depending on the error code. You can handle 404 errors that way…
The last thing you’ll need for the defaultredirect is a simple ErrorController.
public class ErrorController : BaseController
{
//
// GET: /Error/
public ActionResult HttpError()
{
return View("Error");
}
public ActionResult NotFound()
{
return View();
}
public ActionResult Index()
{
return RedirectToAction("Index", "Home");
}
}
The default error view comes in the /views/shared/Error.cshtml folder. This is where MVC will look to find the view to render and display the error message.
@model System.Web.Mvc.HandleErrorInfo
@{
ViewBag.Title = "General Site Error";
}
<h2>A General Error Has Occurred</h2>
@if (Model != null)
{
<p>@Model.Exception.GetType().Name<br />
thrown in @Model.ControllerName @Model.ActionName</p>
<p>Error Details:</p>
<p>@Model.Exception.Message</p>
}
You can overwrite this by passing a view argument to the GlobalFilter, as well as specifying a specifc type of exception, and an order in which to handle the error if you choose to have multiple HandleErrors.
filters.Add(new HandleErrorAttribute
{
ExceptionType = typeof(YourExceptionHere),
// DbError.cshtml is a view in the Shared folder.
View = "DbError",
Order = 2
});




Pingback: The Morning Brew - Chris Alcock » The Morning Brew #992