Content Application Developer Manual / Version 2107
Table Of ContentsThe views rendered for a particular page can be thought of as a tree of views, with the outermost (top-level) at the root of the tree, and each include operation adding another "child". In this nested hierarchy of views, exceptions may be thrown at any time: either because one of the templates has a syntax error and cannot be compiled, because of an I/O error when loading content from the content repository, or for any other reason which may cause exceptions at runtime. By default, exceptions thrown while rendering views are passed all the way "up" the inclusion stack. Exceptions not handled at any level will eventually be handled by the servlet container by forwarding the request to the appropriate error page, if configured appropriately.
In addition to this default exception processing, the CoreMedia CAE provides an ExceptionHandlingViewDecorator to handle exceptions at different levels of the view hierarchy. Using this feature, view exception messages may be shown in the context of the page on which they occurred which is useful to find and fix issues in a development or preview environment. In production environments, the same decorator can simply remove the output of the view causing the error, thus leading to fewer error pages presented to end users at the price of not showing some content on the page.
Activating View Exception Handling
The view exception handling decorator is activated by default. To deactivate it, set
cae.view.errorhandler.enabled=false
Determining How to Handle a View Exception
By default, "handling an exception" means that the output of the view subtree producing the error will be discarded. Note that this mechanism will use additional output buffering, so as - always - it is a good idea to watch out for potential negative effects on temporary heap usage or garbage collection times. However, in most cases this should not be an issue. To render the error message and the exception stack trace on the page (replacing the output of the view subtree producing the error), set the following property in preview or development environments:
cae.view.errorhandler.output=true
The output can be styled using an appropriate CSS style sheet to match the visual appearance of the surrounding page. For instance, a minimal style sheet could show a red box containing the error message while hiding the stack trace, which may become very long:
table.cae-rendererror { border: #FF0000 solid 3px; color: #000000; } table.cae-rendererror .cae-rendererror-stacktrace { display: none; }
To render view exceptions on a page, a fallback view is provided in
the fallbackViewRepository
. To use a custom exception rendering template
rather than the fallback view, add your own view - such as a FreeMarker template -
for
com.coremedia.objectserver.view.ViewException.
Choosing Where to Handle Exceptions
Regardless of whether you suppress output in a production environment or show an error message in a preview or development environment, it is necessary to control where on the page exceptions will be handled. A page usually consists of many nested inline and block elements, all rendered by views in the view tree. It usually makes sense to handle an exception at a certain block level, where it is semantically acceptable to discard erroneous view output or replace it with an error message.
As an example, assume a page with a side bar rendering each item in a collection of content beans using the view name "teaser". The same "teaser" views may also be used in other areas of the page, and each such view again includes many smaller views to include images, video previews, text, metadata and so on. For such application, it is useful to handle exceptions at the "teaser" level, which means that any exception thrown in any of the views making up that teaser view, will be passed up to the "teaser" level for exception handling. In this case, if the "metaData" view included from within the "teaser" threw an exception, the output of the "teaser" view would be discarded completely or replaced completely with an error message, instead of just the "metaData" output.
To control which views should handle exceptions thrown by themselves or views they include,
the ExceptionHandlingViewDecorator is configurable with
accept and reject lists for bean types as well as
view names. Each list may be configured by an appropriate customizer. To continue with the
above example, assume you decide to handle exceptions at the "teaser" level for any
com.example.contentbeans.base.CMObject
:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:customize="http://www.coremedia.com/2007/coremedia-spring-beans-customization"> <customize:append id="addCustomExceptionDecoratorAcceptBeanClasses" bean="exceptionDecoratorAcceptBeanClasses"> <list value-type="java.lang.Class"> <value>com.company.contentbeans.base.CMObject</value> </list> </customize:append> <customize:append id="addCustomExceptionDecoratorRejectBeanClasses" bean="exceptionDecoratorRejectBeanClasses"> <list value-type="java.lang.Class"> <!-- do not add anything --> </list> </customize:append> <customize:append id="addCustomExceptionDecoratorAcceptViews" bean="exceptionDecoratorAcceptViews"> <list value-type="java.util.regex.Pattern"> <value>teaser</value> </list> </customize:append> <customize:append id="addCustomExceptionDecoratorRejectViews" bean="exceptionDecoratorRejectViews"> <list value-type="java.util.regex.Pattern"> <!-- do not add anything --> </list> </customize:append> </beans>
In this example, any exceptions thrown will be passed up the view hierarchy to a view "teaser"
rendered for a bean of type com.example.contentbeans.base.CMObject
, where
it will be handled. The reject lists may be used as a restriction: a view
will only handle an exception, if both accept conditions and no
reject conditions match.
You might instead add java.lang.Object
to
exceptionDecoratorAcceptBeanClasses
and .*
to exceptionDecoratorAcceptViews
, if you wanted any view to handle an
exception. In that case, you should reject beans of
type
com.coremedia.cap.common.Blob, to avoid breaking binary content.