/** * Copyright 2009 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS-IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import("ejs.EJS"); import("funhtml.*"); import("jsutils.{scalaF0,scalaF1}"); import("stringutils.{toHTML,sprintf}"); function _getException(ex) { if (ex instanceof java.lang.Throwable) { return new net.appjet.bodylock.JSRuntimeException(ex.getMessage(), ex); } else if (ex.javaException) { return new net.appjet.bodylock.JSRuntimeException(ex.javaException.getMessage(), ex.javaException); } else if (ex.rhinoException) { return new net.appjet.bodylock.JSRuntimeException(ex.rhinoException.getMessage(), ex.rhinoException); } else { return ex; } } function _convertStackFrameToTable(id, frame) { var r = frame.errorContext(4); var out = []; var t = TABLE({className: "codecontext"}); var counter = r._1(); r._3().foreach(scalaF1(function(s) { var row = TR(TD({className: "linecell"}, counter++), TD(String(s))); if (counter-1 == frame.errorLine()) row[1].attribs['class'] = "offendingline"; t.push(row); })); if (id != 0) out.push(DIV({className: "errorframe", onclick: "toggleFrameView('"+id+"')"}, IMG({className: "zippy", style: "margin-right: 0.5em;", align: "top", src: "http://appjet.com/img/open-arrow.png", id: "image"+id}), SPAN({className: "errordetail"}, "...was called from "+frame.name()+ " (line "+frame.errorLine()+"):"), SPAN({className: "sourceline"}, " "+frame.errorContext(0)._3().first()))); out.push(DIV({id: 'frame'+id, style: (id == 0 ? "" : "display: none;")}, t)); return out.map(function(tag) { return toHTML(tag); }).join(""); } function getStackTraceHTML(ex) { ex = _getException(ex); if (ex.frames().isEmpty()) return "No stack trace available."; var out = []; var counter = 0; var firstFrame = ex.frames().first(); out.push(toHTML(DIV({id: "errortitle"}, "Error in "+firstFrame.name()))); out.push(toHTML(DIV({id: "errormessage"}, ""+ex.cause().getMessage()+" at "+firstFrame.name()+" (Line "+firstFrame.errorLine()+")"))); ex.frames().foreach(scalaF1(function(frame) { out.push(_convertStackFrameToTable(counter++, frame)); })); return out.join(""); } function getStackTraceFullpage(ex) { var tmpl = new EJS({text: _tmpl}); return tmpl.render({trace: getStackTraceHTML(ex)}); } function getStackTracePlain(ex) { ex = _getException(ex); if (ex.frames().isEmpty()) { var cause = ex.cause(); var sw = new java.io.StringWriter(); cause.printStackTrace(new java.io.PrintWriter(sw)); return sw.toString(); } var out = []; var firstFrame = ex.frames().first(); out.push("Error in "+firstFrame.name()); out.push(""+ex.cause().getMessage()+" at "+firstFrame.name()+" (Line "+firstFrame.errorLine()+")"); var counter = 0; ex.frames().foreach(scalaF1(function(frame) { if (counter++ > 0) { out.push(""); out.push("...was called from "+frame.name()+" (line "+frame.errorLine()+"): "+frame.errorContext(0)._3().first()); } var r = frame.errorContext(4); var c2 = r._1(); r._3().foreach(scalaF1(function(s) { var pre = " "; if (c2 == frame.errorLine()) pre = ">"; out.push(sprintf("%s %4s | %s", pre, ""+c2, s)); c2++; })); })); return out.join("\n"); } /* template follows */ var _tmpl = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>AppJet Error</title> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Language" content="en-us" /> <script type="text/javascript" src="http://appjet.com/js/343607636acfee88faa2b638330a3370/jquery-1.2.6.js"></script> <script type="text/javascript"> function toggleFrameView(frameId) { var hidden = $("#frame"+frameId+":hidden") var visible = $("#frame"+frameId+":visible") if (hidden.length > 0) { hidden.show("normal") $("#image"+frameId).attr("src", "http://appjet.com/img/close-arrow.png") } else { visible.hide("normal") $("#image"+frameId).attr("src", "http://appjet.com/img/open-arrow.png") } } function toggleErrorView() { var hidden = $("#hiddentrace:hidden"); var visible = $("#hiddentrace:visible"); if (hidden.length > 0) { hidden.slideDown("normal"); } else { visible.slideUp("normal"); } return false; } function load() { $(".zippy").attr("src", "http://appjet.com/img/open-arrow.png") } </script> <style> body { font-family: verdana, helvetica, sans-serif; font-size: 60%; margin: 1em; } #header { border-bottom: 1px solid red; margin-bottom: 0.8em; } #errortitle { font-weight: bold; font-size: 1.6em; margin-bottom: 0.76em;} #errormessage { font-size: 1.4em; margin-bottom: 1.0em} #errorexplanation { background-color: #ffd; margin: 1em; padding: 0 1em; border: 1px solid #cc9; line-height: 150%; } #errorexplanation ul, #errorexplanation li { margin: 0; padding: 0; } #errorexplanation ul { padding-left: 2em; } #errorexplanation { font-size: 9pt; } #errorexplanation code { font-size: 10pt; } #errorexplanation code { padding: 1px; background: #ddc; margin: 0 5px; white-space:nowrap; } #errorexplanation code.quote { background: #fcc; } #errorexplanation p, #errorexplanation li { margin: 1em 0 } #frame0 { margin-top: 2.0em; } .errorframe { margin-bottom: 0.5em; margin-top: 1em; cursor: pointer; color: blue; } .errordetail { text-decoration: underline; } .errorframe:hover { color: #c47827; } .sourceline { font-size: 1.4em; color: black; font-family: monospace; } #statuscode { float: right; font-size: 2.4em; font-weight: bold; } .codecontext { border: 1px solid black; font-family: monospace; font-size: 1.4em; } .codecontext td { padding: 0.1em 0.3em; } .codecontext .linecell { border-right: 1px solid #888; } .codecontext .offendingline { background-color: #ffcccc; } .errotemplate .codecontext .linecell { border-right: 1px solid black; } pre { margin: 0px; padding: 0px; border: 0px; } #errorexplanation tt { font-size: 85%; color: #666; } </style> </head> <body onload="load()"> <%= trace %> </body> </html>"""