Update: Modified the class to support HTML in the message
Update 2: Made the code compatible with Domino 8.5.2
Update 3: Added methods to display message/exception on pageUpdate 4: Modified to send to current user. If on localhost, the exception/message is thrown -> xpage shows stack trace.
Since there are no good tools for debugging XPages, I created a couple of helper-methods (Server Side Javascript) of my own.
Debug.message sends a (MIME/HTML) mail with the specified message
Debug.exception sends a stack trace of an exception (used in a try/catch). This is useful because not all exceptions crash the application (for instance AfterRenderResponse code).
// Helper-class for debugging
var Debug = {
// Send a stack trace of an exception
exception: function( exception ){
// If on localhost/public db - throw exception
if( this.getUserName() === 'Anonymous' ){ throw exception; }
this.message( this.getExceptionString( exception ), 'Exception!' );
},
// Add exception to page
exceptionToPage: function( exception ){
this.setPageDebugMessage( 'Exception: ' + this.getExceptionString( exception ) );
},
getExceptionString: function( exception ){
var errorMessage = exception.message;
if( typeof exception.printStackTrace !== 'undefined' ){
var stringWriter = new java.io.StringWriter();
exception.printStackTrace( new java.io.PrintWriter( stringWriter ) );
errorMessage = stringWriter.toString();
}
if( typeof exception === 'com.ibm.jscript.InterpretException' ){
errorMessage = exception.getNode().getTraceString() + '\n\n' + errorMessage;
}
return errorMessage;
},
getUserName: function(){
return @Name( '[CN]', @UserName() );
},
// Send a message (supports HTML)
message: function( message, subject ){
// If on localhost/public db - throw exception
if( this.getUserName() === 'Anonymous' ){ throw 'Not logged in. Could not send message: ' + message; }
session.setConvertMime( false );
var doc:NotesDocument = database.createDocument();
doc.replaceItemValue( 'Form', 'Memo' );
doc.replaceItemValue( 'Subject', subject || 'Debug..' );
doc.replaceItemValue( 'SendTo', this.getUserName() );
var body:NotesMIMEEntity = doc.createMIMEEntity();
var contentStream = session.createStream();
// Set preferred styling
contentStream.writeText( '' );
// Convert linefeeds to <br>s
contentStream.writeText( message.replace( '\n', '<br />' ) );
body.setContentFromText( contentStream, 'text/html;charset=ISO-8859-1',
lotus.domino.MIMEEntity.ENC_NONE );
doc.send();
session.setConvertMime( true );
},
// Add message to page
messageToPage: function( message ){
this.setPageDebugMessage( message );
},
// Adds message to the bottom of the page in a dynamically created xp:text
setPageDebugMessage: function( message ){
var messageControl = getComponent( 'global-debug-messages' );
if( !messageControl ){
messageControl = new com.ibm.xsp.component.xp.XspOutputText();
messageControl.setId( 'global-debug-messages' );
messageControl.setEscape( false );
messageControl.setStyleClass( 'xspMessage' );
var valueBinding = facesContext.getApplication().createValueBinding( '#{requestScope.debugMessages}' );
messageControl.setValueBinding( 'value', valueBinding );
view.getChildren().add( messageControl );
}
var currentMessages = requestScope.debugMessages;
if( typeof currentMessages !== 'string' ){ currentMessages = ''; }
requestScope.put( 'debugMessages', message + '<br />' + currentMessages );
}
}