Last active
September 9, 2016 10:42
-
-
Save daniiiol/664d7a0918a4eec9251170755b8ba4e9 to your computer and use it in GitHub Desktop.
Catch the Sitecore MVC Exceptions before executing an application error - The Global Exception Tentacle to avoid Yellow Pages of Death
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> | |
<pipelines> | |
<mvc.exception> | |
<!-- | |
The Global Exception Tentacle to avoid Yellow Pages of Death | |
If ShowExceptionsInPageEditor == true -> The system will throw an exception in the PageEditor | |
If ShowExceptionsInPreview == true -> The system will throw an exception in preview mode | |
If ShowExceptionsInDebugger == true -> The system will throw an exception in debbuger mode | |
--> | |
<processor type="Custom.Project.Core.Processors.GlobalExceptionHandler, Custom.Project.Core" patch:before="*[@type='Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage, Sitecore.Mvc']"> | |
<ShowExceptionsInPageEditor>true</ShowExceptionsInPageEditor> | |
<ShowExceptionsInPreview>false</ShowExceptionsInPreview> | |
<ShowExceptionsInDebugger>true</ShowExceptionsInDebugger> | |
</processor> | |
</mvc.exception> | |
</pipelines> | |
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Configuration; | |
using System.Web.Mvc; | |
using Namics.Opensource.Modules.Logger; | |
using SC = Sitecore; | |
namespace Custom.Project.Core.Processors | |
{ | |
public class GlobalExceptionHandler : Sitecore.Mvc.Pipelines.MvcEvents.Exception.ExceptionProcessor, IExceptionFilter | |
{ | |
/// <summary> | |
/// If Property is true -> The system will throw an exception in the PageEditor | |
/// </summary> | |
public bool ShowExceptionsInPageEditor { get; set; } | |
/// <summary> | |
/// If Property is true -> The system will throw an exception in preview mode | |
/// </summary> | |
public bool ShowExceptionsInPreview { get; set; } | |
/// <summary> | |
/// If Property is true -> The system will throw an exception in debbuger mode | |
/// </summary> | |
public bool ShowExceptionsInDebugger { get; set; } | |
/// <summary> | |
/// The HTTP-Response Header to get an exception information to the client | |
/// </summary> | |
private const string ExceptionHeader = "X-Exception-Code"; | |
/// <summary> | |
/// Raised by mvc.exception pipeline | |
/// </summary> | |
/// <param name="context">The Sitecore pipeline exception context</param> | |
public void OnException(ExceptionContext context) | |
{ | |
Exception ex = context.Exception; | |
// I don't like to manage http exceptions if any guys are trying to get the httpContext in some worker threads... | |
if (!(ex is HttpException)) | |
{ | |
var excp = new SC.Mvc.Pipelines.MvcEvents.Exception.ExceptionArgs(context); | |
this.Process(excp); | |
} | |
} | |
/// <summary> | |
/// Last handling possibility of MVC exceptions in Sitecore | |
/// </summary> | |
/// <param name="args">Sitecore pipeline Exception arguments</param> | |
public override void Process(SC.Mvc.Pipelines.MvcEvents.Exception.ExceptionArgs args) | |
{ | |
// Generation of an autogen Exception-Code to refer between http response code and exception line in the log-file | |
// That's very usefull to search and find an exception between users and DevOps | |
string exceptionCode = Guid.NewGuid().ToString(); | |
HttpContext current = HttpContext.Current; | |
// Log the Exception into the Sitecore log. The Class Logger could be ignored. Please use the normal Sitecore Log feature. | |
Logger.Warn(string.Format( | |
"An Exception occured (({3}) {0} // Request -> {2} : {1}", | |
args.ExceptionContext.Exception.Message, | |
args.ExceptionContext.HttpContext.Request.Url, | |
args.ExceptionContext.HttpContext.Request.HttpMethod, | |
exceptionCode), | |
args.ExceptionContext.Exception); | |
// If occured multiple exceptions, each code would be separated with a "Pipe" | |
if (current.Response.Headers.AllKeys.Contains(ExceptionHeader)) | |
{ | |
current.Response.Headers[ExceptionHeader] = current.Response.Headers[ExceptionHeader] + " | " + | |
exceptionCode; | |
} | |
else | |
{ | |
current.Response.Headers.Add(ExceptionHeader, exceptionCode); | |
} | |
// Control to show an Exception or not | |
if (ShouldShowError()) | |
{ | |
return; | |
} | |
// No Exception would be raised by the System | |
args.ExceptionContext.ExceptionHandled = true; | |
} | |
/// <summary> | |
/// Exception logic | |
/// </summary> | |
/// <returns></returns> | |
protected bool ShouldShowError() | |
{ | |
CustomErrorsMode mode = SC.Configuration.Settings.CustomErrorsMode; | |
return mode == CustomErrorsMode.Off // don't forget the build in CustomErrorMode Logic by Sitecore :-) | |
|| (this.ShowExceptionsInPageEditor && SC.Context.PageMode.IsPageEditor) | |
|| (this.ShowExceptionsInPreview && SC.Context.PageMode.IsPreview) | |
|| (this.ShowExceptionsInDebugger && SC.Context.PageMode.IsDebugging); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment