Estimated reading time:
I see a few different ways of handling errors and error pages in Sitecore. I really like the way that we do it at Lightmaker, it makes things nice and simple and easy to debug! It also allows us as developers to follow good practice in our business and data layers and not worry about exception handling.
CA1031: Do not catch general exception types - Best practice for exception handling says that we should never catch general exception types! If you have this in your code, its time to think again and refactor:
System.Exceptionis the worst possible exception handling strategy. What happens when the application continues executing? It’s probably now in an inconsistent state that will cause extremely hard to debug problems in some unrelated place, or even worse, inconsistent corrupt data that will live on in the database for years to come.
It is so much better to simply allow any exceptins to bubble up to the top of the stack and leave a clear message and stack trace in the error log. Depending on the application, give some indication that there has been a problem in the UI.
In your Sitecore implementation, if you are following a good componentised practice, you probably have a few layers in your code. This is an example of what you might have in an MVC Sitecore project:
Business Layer: Handles getting data from Sitecore for searches or other complex functionality.
Controllers: Communicates with the business layer or Sitecore API to get build a view model and pass it to the view.
Presentation: Views, razor scripts that mix the markup and the data from the view model and present it to the user.
At any point in this flow of data from the Sitecore database to the user and exception could occur. I’m sure you are all good developers and make sure that objects are not null before using them etc… But there are just something that are out of our control!
Also some parts of our code might need to throw an exception. What if a required field has not been filled in by an editor. Somehow, despite validation, something has gone wrong. In these cases we should throw an exception, something has gone wrong and it should be logged and someone notified.
The best thing would be a global exception handler at the application level, that catches any unhandled exception that our application throws. In Sitecore MVC we can do this by overriding the
ExecuteRenderer processor in the
mvc.renderRendering pipeline. In the process method, we can wrap the
base.Process method with a try/catch and then handle any exceptions that occur.
Create this include file to override the processor:
If we catch an exception, we can log the error and also render a custom view in place of the original view for the rendering. Doing this means that we can display meaningful error messages for predefined conditions. A standard setup at Lightmaker is to display the error message if we are in the Page/Experience editor or if
To render the error view, we render the view to a string and use the
RenderRenderingsArgs.Writer to output the reusult:
This means that in our controllers, we can throw a
RenderingParameterException or a
DatasourceNotSet exception if the datasource or rendering parameters have not been set correctly. In the page/experience editor, the user would get a message indicating that the data needs to be fixed. But on the delivery website, the error is hidden from the end users.
Also when debugging the site locally or in a test/qa environment - where we can set custom errors to
Off, we can see the errors being caught.
The razor view for a rendering error would look like this:
For full details of the code, including the methods that are referenced but not listed here - please see the project at https://github.com/GuitarRich/sitecore-exception-handler. This is currently being made into an installable Sitecore package and will be submitted to the Market Place this week.