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.

4
  • 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 Commented Mar 7, 2017 at 15:56
  • I'm on Sitecore 8.1 Update 2 (with no chance of upgrading for this project).
    – Ben
    Commented Mar 7, 2017 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. Commented Mar 7, 2017 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
    Commented Mar 7, 2017 at 16:23

1 Answer 1

11

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

4
  • 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
    Commented Mar 7, 2017 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. Commented Dec 19, 2017 at 8:25
  • Did you find the solution Ben ?Please let me know !
    – user3621
    Commented Oct 17, 2019 at 21:25
  • @HaneenDaoud Yes, you must include some constructors: public ExecuteRenderer() { } and public ExecuteRenderer(Rendering.IRendererErrorStrategy errorStrategy) :base(errorStrategy) { } Commented Jun 5, 2020 at 17:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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