Based on the XSnippet by Tony McGuckin, this version includes some place holders for custom theming (e.g.- logo, styling) and most importantly, code syntax highlighting!
For more, read my blog post on using this custom error XPage.
This is the result of some hair brained ideas of mine and the help of both Marky Roden and Sven Hasselbach via a rather messy Stack Overflow Question. Kudos to both of them for helping me get the perspective and solution I was looking or.
The Google Code Prettify script is used (you could host it from non-CDN source) to generate the appropriate code highlighting with the error and stack trace code blocks being wrapped in a <pre>
tag with the prettyprint
class. When the JS script is invoked, it runs some JS to determine keywords, transforms some HTML accordingly, and then loads CSS to style those keywords.
In an NSF which implements a custom error XPage, as mine do (mostly to take advantage of the OpenLog Logger for XPages OSGi plugin), when an XPage encounters a runtime error on a full refresh it loads the error page. This is different from a partial refresh, which loads the error page content via a dojo xhr, which is subject to the rules of innerHTML and nonevaluating JS script blocks. In other words, a <script>
tag, while present and working for a full refresh, doesn't trigger by being loaded as content from an AJAX load.
I pointed out in one of my updates to my question that the images still loaded fine, which they do (as does a <style>
tag), making this specific to the <script>
blocks. As Sven's (third!) answer demonstrated, we can achieve JS execution within the onload attribute of an <img>
tag. This simplifies things for me considerably and yields the solution now in my Error page.
When the page loads via a full refresh, it does its normal behavior via a <script>
tag. Nothing special here.
When the partial refresh retrieves the custom error XPage, it computes an xp:text
's rendered property and loads, with a src of a 1px x 1px image (base-64 encoded, guarantees that an image loads with something) and fires an onload event of creating a <script>
tag and appending it to the <head>
of the DOM.
This requires no external dependencies or XHR hijacks (which I thought I would need for all pages, to be added in a JS file via a theme). To me, the simplicity here is sheer elegance.