9

I've edited a patched a pipeline using the following bit of code.

<sitecore>
  <pipelines>
    <mvc.exception>
      <processor type="Sitecore.Mvc.Pipelines.MvcEvents.Exception.ShowAspNetErrorMessage, Sitecore.Mvc">
        <patch:attribute name="type">ProjectName.PublicSite.Web.App_Pipelines.ExceptionHandler.ExceptionHandler, ProjectName.PublicSite.Web</patch:attribute>
    </processor>
</mvc.exception>

In addition, I've created the following class to handle things that fall in the mvc.exception pipeline.

namespace ProjectName.PublicSite.Web.App_Pipelines.ExceptionHandler
{
using Sitecore.Mvc.Pipelines.MvcEvents.Exception;
using Sitecore.Diagnostics;
using System.Configuration;
using System.Web.Configuration;

public class ExceptionHandler : ExceptionProcessor
{
    public override void Process(ExceptionArgs args)
    {
        var context = args.ExceptionContext;
        var httpContext = context.HttpContext;
        var exception = context.Exception;

        if (context.ExceptionHandled || httpContext == null || exception == null || !httpContext.IsCustomErrorEnabled)
        {
            return;
        }
        else
        {
            Log.Error(exception.Message, exception);

            httpContext.Server.ClearError();
            string redirect = "/error";
            httpContext.Response.Redirect(redirect, false);
        }
    }
}

}

The problem that I'm having is that this only handles certain exceptions that can occur, as detailed here and here. I'd like to handle other exceptions that can arise. I've tried adding the following code to the Global.asax.cs file.

protected void Application_Error (object sender, EventArgs e)
{
    Sitecore.Diagnostics.Log.Error("This is an error.", sender);
}

However, I'm not able to get it to hit when I throw an exception in the code. My overall goal is to be able to log any exceptions that may occur in the Sitecore logs.

  • 1
    What version of Sitecore are you using? Sitecore 8.2 moved to a private global.asax, so you won't be able to directly add code to it. You would need to patch the code in through the pipeline – Patrick Barron Mar 7 '17 at 15:56
  • I'm on Sitecore 8.1 Update 2 (with no chance of upgrading for this project). – Ben Mar 7 '17 at 16:02
  • i would suggest to handle rendering exception which would catch almost all exceptions while rendering a page in live site. if this is what you need i can provide some detailed info. – Balaji Kuppuswamy Mar 7 '17 at 16:12
  • Aren't rendering exceptions already handled by the mvc.exception pipeline? I was able to test that by changing the path of a rendering to something that was invalid. Let me know if you're referring to something else. – Ben Mar 7 '17 at 16:23
10

So for Sitecore - a global error handler in the global.asax will not work properly. The better way to do it is to override the code that calls each rendering and handle the errors there.

ExecuteRenderer

With a simple override of ExecuteRenderer we can easily catch all exceptions:

public class ExecuteRenderer : Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer
{
    public override void Process(RenderRenderingArgs args)
    {
        try
        {
            base.Process(args);
        }
        catch (Exception ex)
        {
            args.Cacheable = false;
            // TODO: Log the error here and deal with how you want to display it to the user
            Log.Error(ex.Message, ex, this);
        }
    }
}

Notice that we are setting args.Cacheable = false - that means that this error handler will work nicely with cached renderings too.

To enable it, simply patch the processor in, replacing the existing one:

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <pipelines>
            <mvc.renderRendering>
                <processor type="Sitecore.Mvc.Pipelines.Response.RenderRendering.ExecuteRenderer, Sitecore.Mvc">
                    <patch:attribute name="type">Sitecore.Exception.Handler.Pipelines.Response.RenderRendering.RenderRendering.ExecuteRenderer, Sitecore.Exception.Handler</patch:attribute>
                </processor>
            </mvc.renderRendering>
        </pipelines>
    </sitecore>
</configuration>

Now you have a global error handler, that will trap errors per rendering. This allows the rest of the site to continue to load nicely and just hides the offending rendering.

For more detail and some more ideas, see my original blog post here Sitecore Rendering Exception Handling

| improve this answer | |
  • 2
    Thanks for this. I gave it a try, and it catches the same error that I'd been testing above with the mvc.exception pipeline (basically, a misspelling in a rendering path). My main question was that I'd like to catch any error that could arise. For testing, I have a line of code that I'm hitting that says the following. throw new System.Web.HttpException("This error is intentional."); As far as you are aware, can I set something up to handle any type of exception (not just rendering ones)? – Ben Mar 7 '17 at 19:23
  • Thanks for your solution. a processor returned "Could not create instance of type: "Sitecore.Exception.Handler.Pipelines.Response.RenderRendering.RenderRendering.ExecuteRenderer" No matching constructor was found. that because process method in sitecore.MVC is already overridden. – Haneen Daoud Dec 19 '17 at 8:25
  • Did you find the solution Ben ?Please let me know ! – user3621 Oct 17 '19 at 21:25
  • @HaneenDaoud Yes, you must include some constructors: public ExecuteRenderer() { } and public ExecuteRenderer(Rendering.IRendererErrorStrategy errorStrategy) :base(errorStrategy) { } – Marcel Jun 5 at 17:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.