Sitecore redirect on errors

NomadTraveler picture NomadTraveler · Jul 16, 2015 · Viewed 8.3k times · Source

I know that I can extend Sitecore.Pipelines.HttpRequest.ExecuteRequest and override methods like RedirectOnItemNotFound to redirect to my custom 404 page etc. I was wondering if there is way to redirect to a custom page (that would sit in sitecore) for all errors except 404 and 500?

There is a RedirectOnNoAccess method for 403 error I guess, but I am looking for way to redirect on all errors like 400, 401, 403, 405 etc.

Sitecore v7.2

Cheers

Answer

jammykam picture jammykam · Jul 16, 2015

You don't need to extend the ExecuteRequest processor, there are settings in the Sitecore section of config to handle these:

<!--  ITEM NOT FOUND HANDLER
        Url of page handling 'Item not found' errors
  -->
<setting name="ItemNotFoundUrl" value="/sitecore/service/notfound.aspx"/>

<!--  LINK ITEM NOT FOUND HANDLER
        Url of page handling 'Link item not found' errors
  -->
<setting name="LinkItemNotFoundUrl" value="/sitecore/service/notfound.aspx"/>

<!--  LAYOUT NOT FOUND HANDLER
        Url of page handling 'Layout not found' errors
  -->
<setting name="LayoutNotFoundUrl" value="/sitecore/service/nolayout.aspx"/>

<!--  ACCESS DENIED HANDLER
        Url of page handling 'Acess denied' errors
  -->
<setting name="NoAccessUrl" value="/sitecore/service/noaccess.aspx"/>

Update these values to point to the correct path. This can be a Sitecore item path, e.g. /errors/404 as long as that item exists in Sitecore. It's slightly annoying that a url parameter is added to the path, you will need to extend the processor if you want to get rid of this though. If you have a multi-site implementation then this will still work but you need to make sure that the structure is the same for all sites, since you are using a relative path. The error manager module is essentially a wrapper around these same settings, but it is better in that it is able to handle multi-site and shows the error page without making a 302 redirect first.

If you need to handle other errors then fallback to using the errors section in config to define those. The values can also be set through IIS (although it just updates the web.config anyway)

<system.webServer>
  <httpErrors errorMode="DetailedLocalOnly" defaultResponseMode="ExecuteURL" defaultPath="/errors/404">
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="405" subStatusCode="-1" />
    <remove statusCode="500" subStatusCode="-1" />
    <error statusCode="404" prefixLanguageFilePath="" path="/errors/404" responseMode="ExecuteURL" />
    <error statusCode="405" prefixLanguageFilePath="" path="/errors/405" responseMode="ExecuteURL" />
    <error statusCode="500" prefixLanguageFilePath="" path="/errors/static/500.html" responseMode="ExecuteURL" />
  </httpErrors>
</system.webServer>

These can be in Sitecore by setting the URL path of an Item or static HTML files on disk, and again it works in multi-site as long as the structure is the same for all sites since the path can be relative. It is generally recommended that the 500 page is a static HTML page otherwise there is the possibility of an infinite loop (e.g. database goes down, show 500, fetch content from Sitecore, but database is down...).

Even if you use the Error Manager module, or use the Sitecore settings, I recommend that you have a 404 and 500 page defined in config. By default Sitecore will only handle dynamic and extentionless URL requests, so if a request is made for /file.txt, /style.css, /script.js or /document.pdf then you will get a standard IIS error page.

<preprocessRequest>
  <processor type="Sitecore.Pipelines.PreprocessRequest.FilterUrlExtensions, Sitecore.Kernel">
    <param desc="Allowed extensions (comma separated)">aspx, ashx, asmx</param>
    <param desc="Blocked extensions (comma separated)">*</param>
    <param desc="Blocked extensions that stream files (comma separated)">*</param>
    <param desc="Blocked extensions that do not stream files (comma separated)"></param>
  </processor>
</preprocessRequest>

You could allow all requests to go through Sitecore but this seems a bit heavy handed and you're making it run through additional pipelines. Setting the above will mean your static content is also gracefully handled.