title: Custom Error XPage: Ability for Browser to Load and Execute JS Script Link or Block After Being Loaded On Error
body: <p><strong>Situation</strong></p>
  
  <p>I'm using a custom error XPage, based highly off of <a href="http://openntf.org/XSnippets.nsf/snippet.xsp?id=custom-error-page-cw-cause-and-stacktrace-information" rel="nofollow noreferrer">the XSnippet from Tony McGuckin</a>. It works rather well but I would like for the browser to execute a client-side JavaScript block (or load and run a JS file from a given URL). If I navigate directly to the custom error XPage, it loads correctly, but given the nature of how it loads on redirect from a SSJS runtime error, it seems to load any attempts at loading a script block in the head tag, inside the body tag. I've attempted passing through a JS script tag in the body (shown in the code below), attempted <a href="http://www.intec.co.uk/how-to-get-a-head-in-xpages-repost-previous-version-corrupted/" rel="nofollow noreferrer">using the <em>xp:headTag</em> inside <em>xp:resources</em></a>, and attempted <a href="https://tobysamples.wordpress.com/2013/03/13/script-resources-in-xpages/" rel="nofollow noreferrer">via an <em>xp:script</em> tag in <em>xp:resources</em></a>.</p>
  
  <p><strong>Browser's Perspective</strong></p>
  
  <p>From the browser's perspective, after encountering a runtime error during an event that invokes SSJS during a partial refresh, the xhr being invoked returns with a 500 and sets the content into the body tag (screen shot).</p>
  
  <p><img src="https://i.stack.imgur.com/MkFvS.png" alt="error XPage loading"></p>
  
  <p>When viewing the response contents, the entire custom error XPage is there, including the <code>&lt;script type="text/javascript"&gt;console.log("hello world");&lt;script&gt;</code>. This does not seem to trigger or put anything out to the JS console of the browser. What is visible via the JS console is some garbage from dojo complaining about getting back an XHR with response code of 500 (my dojoConfig is set to <code>isDebug: true</code> via <em>xsp.client.script.dojo.djConfig</em> in XSP Properties).</p>
  
  <p><strong>Question</strong></p>
  
  <p>Is there a way to get a client-side JS script tag to load and execute in the browser after an error 500 which occurs during the loading of a custom error XPage?</p>
  
  <p><hr />
  Here's the code for my Error page. To reproduce my results, invoke an SSJS action resulting in a runtime error (such as the <a href="https://github.com/paulswithers/openlogjava/blob/master/OpenLogJava/XPages/ErrorOnClick.xsp" rel="nofollow noreferrer">ErrorOnClick XPage</a> included in the OpenLog Logger for XPages project from Paul Withers) with a partial refresh event.</p>
  
  <p><strong>Error.xsp</strong> (set as the error page in XSP Properties)
  </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;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'}"&gt;
      &lt;style
          type="text/css"&gt;&lt;![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;
          }
    ]]&gt;&lt;/style&gt;
      &lt;img
          class="logo-simple"
          src="//placehold.it/124x32" /&gt;
      &lt;xp:panel&gt;
          &lt;xp:br&gt;&lt;/xp:br&gt;
          &lt;xp:br&gt;&lt;/xp:br&gt;
          &lt;xp:label
              style="font-weight:bold;font-size:12pt"
              value="An Unexpected Error Has Occurred:"&gt;
          &lt;/xp:label&gt;
          &lt;xp:br&gt;&lt;/xp:br&gt;
          &lt;xp:br&gt;&lt;/xp:br&gt;
          &lt;xp:label
              value="Error:"&gt;&lt;/xp:label&gt;
          &lt;xp:br /&gt;
          &lt;xp:text
              escape="false"&gt;
              &lt;xp:this.value&gt;&lt;![CDATA[#{javascript:if( !!requestScope.error ){
      var output = (requestScope.error.toString() || null)+"&lt;br /&gt;&lt;br /&gt;";
      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 + "&lt;br /&gt;&lt;br /&gt;";
          if(cause instanceof com.ibm.jscript.InterpretException){
              var errorLine = cause.getErrorLine();
              var errorColumn = cause.getErrorCol();
              output += "At line " + errorLine;
              output += ", column " + errorColumn + " of:&lt;br /&gt;";
          }else{
              output += "In the script:&lt;br /&gt;";
          }
          if( @Contains(codeSnippet,"#{javascript:") ){
              var snipAr = codeSnippet.split("#{javascript:");
              var tmpSnip = snipAr[1];
              var nwSnip = tmpSnip.substring(0, tmpSnip.length - 1);
              output += "#{javascript:&lt;br /&gt;&lt;pre&gt;"+nwSnip+"&lt;/pre&gt;}"
          }else{
              output += codeSnippet;
          }
      }
      return output;
  }else{
      return "";
  }}]]&gt;&lt;/xp:this.value&gt;
          &lt;/xp:text&gt;
          &lt;xp:br&gt;&lt;/xp:br&gt;
          &lt;xp:br&gt;&lt;/xp:br&gt;
          &lt;xp:label
              value="Stack Trace:"&gt;&lt;/xp:label&gt;
          &lt;xp:br /&gt;
          &lt;xp:text
              escape="false"
              style="font-size:10pt"&gt;
              &lt;xp:this.value&gt;&lt;![CDATA[#{javascript:if( !!requestScope.error ){
      var stackTrace = "";
      var trace = (requestScope.error.getStackTrace() || null);
      if(trace != null){
          for(var i = 0; i &lt; trace.length; i++){
              stackTrace += trace[i] + "&lt;br/&gt;";
          }
          return "&lt;pre&gt;"+stackTrace+"&lt;/pre&gt;";
      }else{
          return "nothing";
      }
  }else{
      return "";
  }}]]&gt;&lt;/xp:this.value&gt;
          &lt;/xp:text&gt;
      &lt;/xp:panel&gt;
      &lt;script
          type="text/javscript"&gt;
          &lt;![CDATA[console.log("Hello world...");]]&gt;
      &lt;/script&gt;
  &lt;/xp:view&gt;
  </code></pre>
  
  <p>For what it's worth: I didn't find anything explicitly on this subject via a search of Google or StackOverflow.</p>
  
  <p><hr />
  UPDATE 1:
  This was a case of either caffeine deprivation or just not seeing the forest through the trees. It helps to not use a CDATA block in your HTML code. The lazy developer in me tried copying and pasting between an <em>xp:script</em> block and the HTML <em>&lt;script&gt;</em> block, preserving it. Now for the public shaming of buying Marky beer in Atlanta.</p>
  
  <p>UPDATE 2:
  Marky's beverage of choice may be in peril. While I seem to have had issues with copying a CDATA tag in, the issue remains. In my efforts to produce a simplified page with a button to error out (loosely based on the above mentioned XPage from the OpenLog Logger for XPages ErrorOnClick.xsp), I mistakenly took out a part of what was causing my issues in the first place, the partial refresh. When I do a full refresh, no issue, but when I do a partial, it doesn't load. I'm enclosing a sample page to trigger an error, with two buttons; one to induce a full, the other a partial. SO, with a full refresh, I get an alert of "hello world...", with the partial, no dice.</p>
  
  <p><strong>MakeSomeError.xsp</strong>
  </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;xp:view
      xmlns:xp="http://www.ibm.com/xsp/core"&gt;
      &lt;xp:panel
          id="somePanel"&gt;
          &lt;xp:button
              value="Failing Partial"
              id="button1"&gt;
              &lt;xp:eventHandler
                  event="onclick"
                  submit="true"
                  refreshMode="partial"
                  refreshId="somePanel"&gt;
                  &lt;xp:this.action&gt;&lt;![CDATA[#{javascript:var a:NotesDateTime = null;
  viewScope.myStuff = a.toJavaDate().toDateString();}]]&gt;&lt;/xp:this.action&gt;
              &lt;/xp:eventHandler&gt;
          &lt;/xp:button&gt;
          &lt;xp:button
              value="Failing Full"
              id="button2"&gt;
              &lt;xp:eventHandler
                  event="onclick"
                  submit="true"
                  refreshMode="complete"&gt;
                  &lt;xp:this.action&gt;&lt;![CDATA[#{javascript:var a:NotesDateTime = null;
  viewScope.myStuff = a.toJavaDate().toDateString();}]]&gt;&lt;/xp:this.action&gt;
              &lt;/xp:eventHandler&gt;
          &lt;/xp:button&gt;
          &lt;xp:br /&gt;
          &lt;xp:text
              value="#{viewScope.myStuff}" /&gt;
      &lt;/xp:panel&gt;
  &lt;/xp:view&gt;
  </code></pre>
  
  <p>UPDATE 3:
  Okay. Sven's second answer has me very close, but for some reason I can't extrapolate just enough to get what I want to happen to occur. I'm including a GIF below of my results. The only thing different I would like to have happen is for my Error.xsp (custom error XPage) to continue loading after I encounter the error (it seems like I'll need to change the <em>beforeRenderResponse</em> block to an <em>afterRenderResponse</em> script perchance?). I want to append the script, not replace the Error.xsp loading. Basically, I'm trying to run a script after the error XPage is loaded (there's a helper JS file I'm trying to load into my custom error XPage, CSS is loading fine, just not the JS lib). I would love to:</p>
  
  <ol>
  <li>get this working</li>
  <li>share what it is (it's kind of cool, if I do say so myself)</li>
  </ol>
  
  <p><img src="https://i.stack.imgur.com/WPJP4.gif" alt="results of Sven&#39;s second answer"></p>