Custom Error XPage w/ Syntax Highlighting of Code Blocks

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
	xmlns:xp="http://www.ibm.com/xsp/core"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.ibm.com/xsp/core xsdxp://localhost/xsp~core.xsd"
	pageTitle="${javascript:database.getTitle() + ' | Error'}">
	<style
		type="text/css"><![CDATA[
		body {
			background-color: lightblue;
		}
		form {
			width: 1000px !important;
			margin: 0 auto !important;
			background-color: white !important;
			margin-top: 2rem !important;
			padding: 0.5rem !important;
			height: auto;
		}
		.xspTextLabel {
			font-weight: bold !important;
		}
		pre {
			overflow-x: auto;
		}
  ]]></style>
	<img
		class="logo-simple"
		src="//placehold.it/124x32" />
	<xp:panel>
		<xp:br />
		<xp:br />
		<xp:label
			style="font-weight:bold;font-size:12pt"
			value="An Unexpected Error Has Occurred:">
		</xp:label>
		<xp:br />
		<xp:br />
		<xp:label
			value="Error:"></xp:label>
		<xp:br />
		<xp:text
			escape="false">
			<xp:this.value><![CDATA[#{javascript:var output = (requestScope.error.toString() || null)+"<br /><br />";
if(requestScope.error instanceof com.ibm.xsp.exception.XSPExceptionInfo){
	var codeSnippet = requestScope.error.getErrorText(); 
	var control = requestScope.error.getErrorComponentId();
	var cause = requestScope.error.getCause();
	output += "In the control : " + control + "<br /><br />";
	if(cause instanceof com.ibm.jscript.InterpretException){
		var errorLine = cause.getErrorLine();
		var errorColumn = cause.getErrorCol();
		output += "At line " + errorLine;
		output += ", column " + errorColumn + " of:<br />";
	}else{
		output += "In the script:<br />";
	}
	if( @Contains(codeSnippet,"#{javascript:") ){
		var snipAr = codeSnippet.split("#{javascript:");
		var tmpSnip = snipAr[1];
		var nwSnip = tmpSnip.substring(0, tmpSnip.length - 1);
		output += "#{javascript:<br /><pre class=\"prettyprint\">"+nwSnip+"</pre>}"
	}else{
		output += "<pre class=\"prettyprint\">"+codeSnippet+"</pre>";
	}
}
return output;}]]></xp:this.value>
		</xp:text>
		<xp:br />
		<xp:br />
		<xp:label
			value="URL:" />
		<xp:br />
		<xp:text
			escape="false"
			style="font-size:10pt;border-color:rgb(64,0,0);font-family:serif"
			value="#{javascript:return context.getUrl();}">
		</xp:text>
		<xp:br />
		<xp:br />
		<xp:label
			value="Stack Trace:" />
		<xp:br />
		<xp:text
			escape="false"
			style="font-size:10pt">
			<xp:this.value><![CDATA[#{javascript:if( !!requestScope.error ){
		var stackTrace = "";
		var trace = (requestScope.error.getStackTrace() || null);
		if(trace != null){
			for(var i = 0; i < trace.length; i++){
				stackTrace += trace[i] + "<br/>";
			}
			return "<pre class=\"prettyprint\">"+stackTrace+"</pre>";
		}else{
			return "nothing";
		}
	}else{
		return "";
	}}]]></xp:this.value>
		</xp:text>
	</xp:panel>
	<script
		type="text/javascript"
		src="//cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"></script>
	<xp:text
		escape="true"
		id="executeOnAjax"
		tagName="img">
		<xp:this.attrs>
			<xp:attr
				name="src"
				value="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" />
			<xp:attr
				name="onload"
				value="var h=document.getElementsByTagName('head')[0],s=document.createElement('script');h.src=''//cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert',h.appendChild(s);this.parentNode.removeChild(this);" />
		</xp:this.attrs>
		<xp:this.rendered>
			<![CDATA[#{javascript:var ex = facesContext.getExternalContext();
var pMap = com.ibm.xsp.util.TypedUtil().getRequestParameterMap(ex);
var refreshId = pMap.get("$$ajaxid");
refreshId?true:false;}]]>
		</xp:this.rendered>
	</xp:text>
</xp:view>





Based on the XSnippet by Tony McGuckin, this version adds some styling and formats the code blocks (for both cause and stack trace) inside HTML pre tags. This version also introduces the use of Google Code Prettify, which will perform syntax highlighting automagically. The neat part is that this works, even if the runtime error is via a partial refresh, as it forces the load and JS highlighting effect via an img tag's onload property.

Original XSnippet by Tony McGuckin: http://openntf.org/XSnippets.nsf/snippet.xsp?id=custom-error-page-cw-cause-and-stacktrace-information
My blog post on this custom error XPage: http://edm00se.io/xpages/custom-error-xpage

Updated 01-June-2016 to add URL field (context.getUrl()) as it's handy, for when a user actually sends a screen shot, but chops off the address bar.

XPages
Eric McCormick
July 4, 2015 12:54 PM
Rating
40

All code submitted to OpenNTF XSnippets, whether submitted as a "Snippet" or in the body of a Comment, is provided under the Apache License Version 2.0. See Terms of Use for full details.



No comments yetLogin first to comment...