Skip to content

Instantly share code, notes, and snippets.

@andrewbranch
Last active December 18, 2015 02:18
Show Gist options
  • Save andrewbranch/5709593 to your computer and use it in GitHub Desktop.
Save andrewbranch/5709593 to your computer and use it in GitHub Desktop.
Files (or snippets of files) to set up a highly flexible custom errors system that works for jQuery AJAX and synchronous calls alike for an ASP.NET MVC project.
// Include in all Error Views
// In conjunction with main.js, allows browser "back" navigation
// to clear the error page if the user got here via a bad AJAX call.
$(window).hashchange(function() {
location.reload();
});
using System.Net;
using System.Web.Mvc;
namespace ProjectName.Controllers
{
public class ErrorController : Controller
{
public ViewResult NotFound() {
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ViewResult InternalError() {
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return View();
}
public ViewResult Unauthorized() {
Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return View();
}
}
}
//Include in Global.asax.cs
//Be sure to define DEBUG symbol in project settings
#if !DEBUG
protected void Application_Error() {
var exception = Server.GetLastError();
var httpException = exception as HttpException;
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = "InternalError";
routeData.Values["exception"] = exception;
Response.StatusCode = 500;
if (httpException != null) {
Response.StatusCode = httpException.GetHttpCode();
switch (Response.StatusCode) {
case 403:
routeData.Values["action"] = "Unauthorized";
break;
case 404:
routeData.Values["action"] = "NotFound";
break;
}
}
IController errorsController = new ErrorController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
#endif
// Include in all files with jQuery AJAX calls
// When an AJAX call returns a response with an error code,
// Replace the open document with the error page.
if (!DEBUG) {
$(document).ajaxError(function(event, jqxhr, settings, exception) {
location.hash = "#error";
var errorView = document.open("text/html", "replace");
errorView.write(jqxhr.responseText);
errorView.close();
});
}
// A non-essential call can cancel the global ajaxError event by setting global to false, e.g.
$.ajax({
url: url,
type: "GET",
data: { id: 1 },
global: false,
}).done(function(data) {
// Celebrate
}).fail(function(data) {
// Handle the error with more poise. Also great for debugging/admin apps.
$("#alert").html('Error deleting. See <a href="#">error page</a>.');
$("#alert a[href=#]").click(function(event) {
event.preventDefault();
errorWindow = window.open();
var errorView = errorWindow.document.open("text/html", "replace");
errorView.write(data.responseText);
errorView.close();
});
});

MVC Custom Errors Setup

Files (or snippets of files) to set up a highly flexible custom errors system that works for jQuery AJAX and synchronous calls alike for an ASP.NET MVC project.

Global.asax.cs
during any application error, attempts to render appropriate view via ErrorsController action
Controllers/Errors/ErrorsController
renders the error views, could do custom logging
Scripts/main.js
turns on global jQuery AJAX error event to display the error page after a bad AJAX call
Scripts/errors.js
enables navigation out of error page when rendered after AJAX
Web.config
enables static custom error pages as a backup
Site.Master
Exposes Debug symbol to JavaScript
<!-- somewhere in the <head> -->
<script>
window.DEBUG = <%= HttpContext.Current.IsDebuggingEnabled.ToString().ToLower() %>;
</script>
<!-- Fall back to static error pages (if anything goes wrong with Global.asax or ErrorsController or associated Views) -->
<configuration>
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="InternalError.html">
<error statusCode="403" redirect="~/Content/html/Unauthorized.html"/>
<error statusCode="404" redirect="~/Content/html/NotFound.html"/>
</customErrors>
</system.web>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment