6

I found a similar question, but could not find out what I need from there

I am trying to achieve a language-specific, content manageable, friendly error message page for 500 status code.

What I have done so far is:

  • Added a new processor in httpRequestEnd pipeline after Sitecore.Pipelines.HttpRequest.EndDiagnostics
  • Finding if there is any internal server error.
  • If there is, getting error Item from sitecore.

    public class Handle500Erros : HttpRequestProcessor
    {
    public override void Process(HttpRequestArgs args)
    {
    
        if (args?.Context?.Response.StatusCode == (int)HttpStatusCode.InternalServerError)
        {
            var errorPageItem =
            Sitecore.Context.Database.GetItem(string.Concat(Sitecore.Context.Site.StartPath, Settings.ErrorPage));
            if (errorPageItem!= null && Sitecore.Context.Item.ID!= errorPageItem.ID)
            {
                Sitecore.Context.Item = errorPageItem;
                //var htmlForErrorPageForSpecificlanguage = GetHtmlforErrorItem
                // set response html to htmlForErrorPageForSpecificlanguage
            }
        }
    }
    }
    

Let's assume my error Item name in sitecore is 500Error

Now my question is:

  • How to get Html for the error sitecore Item?
  • How to write that to response, seems like args.Context.Response is readonly?

So if some error comes up at 500Error item I am just skipping this step, so there won't be any infinite loops happening.

Am I over complicating? is there a better way to do this?

4
  • I have checked that question already, the suggested answer there is to go for static html pages for 500 staus code. But i am looking after language specific error pages. Jan 17, 2017 at 12:49
  • You're after an IIS feature then, assuming static content 500 error pages. blogs.msdn.microsoft.com/benjaminperkins/2013/03/01/… Jan 17, 2017 at 13:18
  • No, i am after different error pages(comes from sitecore) for different languages. Jan 17, 2017 at 13:49
  • 2
    Don't serve 500 error pages from Sitecore Jan 17, 2017 at 14:32

2 Answers 2

10

You want to use a static html page for this as otherwise you could end up in an endless loop.

You can do this in your web.config like so:

<customErrors mode="RemoteOnly" xdt:Transform="Replace">
   <error redirect="/error.html" statusCode="500" />
</customErrors>

You can then add a rewrite rule for each site to actually load a different static page for each site from a folder in your solution like so:

  <rule name="Server Error Rule" stopProcessing="true" enabled="true">
      <match url=".*" />
      <conditions>
        <add input="{URL}" pattern="^/error.html$" />
        <add input="{HTTP_HOST}" pattern="^(admin|www).(mysite1|mysite2|mysite3)?.*.(com|co.uk)" />
      </conditions>
      <action type="Rewrite" url="/errors/{C:2}.html" />
    </rule>

You will not be able to show info regarding the Sitecore item or other things that caused issues using this approach but I think it is risky to do so in case of Database connectivity issues and so forth. You would instead look at your Sitecore log files to find out what caused the problem.

5
  • Thanks, this works for static html pages, i am after content manageable error pages Jan 17, 2017 at 14:29
  • @DheerajPalagiri I would advise against this in case of Database connectivity issues, solr issues or anything else your website relies on that might be loaded by your content managed 500 error page. You will end up in a continuous error loop. Bad Idea. Instead just manually manage the content of these pages or maybe publish the content out as json/xml or something from Sitecore as static files and then load these into the page using C# code that has no reliance on the rest of your Site or Sitecore working . Jan 17, 2017 at 15:07
  • By the nature of a 500 error, you should not use content manageable pages for 500 errors. A 500 error means that something has gone very wrong and redirecting to a Sitecore served page has a high chance of failing again.
    – Richard Seal
    Jan 17, 2017 at 15:08
  • @AdamSeabridge can't i just skip infinite looping by checking Sitecore.Context.Item.ID != errorPageItem.ID ? or am i missing the whole point. please see the full code in my question. Jan 17, 2017 at 15:14
  • @DheerajPalagiri I think you are missing the point I'm afraid. A 500 error can be generated from anywhere in your application regardless of if Sitecore or an item in Sitecore is throwing an error. It might be something else entirely. If it is Sitecore and your database connection fails then this line could well blow up 'Sitecore.Context.Database.GetItem(string.Concat...)' which would mean you will get a 500 error, which will re-direct to this page which will blow up again and so forth. You could perhaps wrap some of this in a try{}catch{} but in general this is bad practice. Jan 17, 2017 at 15:20
2

Adam is on point!

That is the best approach I've found to work with any Sitecore install.

Here is what I ended up doing - with some explanation around it..

Insert the following into your Web.Config

Inside <system.webServer>

<rewrite>
    <rules>
        <rule name="CustomApplicationErrorPage" patternSyntax="ECMAScript">
            <match url="(ApplicationError.htm)" />
            <action type="Rewrite" url="/errors/{C:0}ApplicationError.html" appendQueryString="false" />
            <conditions logicalGrouping="MatchAny">
                <add input="{HTTP_HOST}" pattern="(google)" />
                <add input="{HTTP_HOST}" pattern="(walmart)" />
            </conditions>
        </rule>
    </rules>
</rewrite>

What I am doing is looking for inbound requests to the default error page.

In the case of this client it is ~/ApplicationError.htm

So my rule is to check for that route.. and my conditions look at just the HTTP_HOST (domain name) and I set regex to look for specific domain names

And then I use those to rewrite the inbound traffic to a dynamic custom error pages stored in the /errors/ folder on webroot. using the {C:0} token.

www.google.com | regex (google) => rewrite to /errors/googleApplicationError.html
www.walmart.com | regex (walmart) => rewrite to /errors/walmartApplicationError.html

I hope this helps.

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