Author: ptw
Date: 2009-09-16 12:13:37 -0700 (Wed, 16 Sep 2009)
New Revision: 14763
Added:
openlaszlo/trunk/test/lpp-8222.lzx
Modified:
openlaszlo/trunk/WEB-INF/lps/lfc/build.xml
openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzBootstrapDebugService.lzs
openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzDebugStub.lzs
openlaszlo/trunk/WEB-INF/lps/lfc/debugger/LzDebug.lzs
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
Log:
Change 20090915-ptw-g by [email protected] on 2009-09-15 13:50:47 EDT
in /Users/ptw/OpenLaszlo/trunk-2
for http://svn.openlaszlo.org/openlaszlo/trunk
Summary: Improve debugging of runtime errors
Bugs Fixed: LPP-8222 "User errors" don't work if catcherrors is turned on
Technical Reviewer: [email protected] (pending)
QA Reviewer: henry (Message-ID:
<[email protected]>),
[email protected] (Message-ID: <[email protected]>
)
Release Notes:
The debugger will now, by default, intercept runtime errors
(instances of Error that are thrown by the runtime or program) and
report them, to minimize the need to use the platform debuggers
for DHTML and swf9 (or later) when debugging LZX programs.
These reports can be silenced by throwing values that are not
instances of Error (the best choice if you are using try/catch for
control flow, not for error situations), or by adding: #pragma
"throwsError=true" to the function or method contaning the throw.
The reporting feature is independent of the lps.properties setting
compiler.catcherrors (which can be used to ignore runtime errors
in production code), however the #pragma will also prevent
compiler.catcherrors from interfering with the throw of an Error
object.
[This feature is not implemented in swf8, because uncaught errors
are always ignored in that runtime.]
Details:
test/lpp-8222: test throwing of a non-error, throwing an
uncaught error, throwing a caught error, and throwing a caught
error using the #pragma. The test is self-documenting and adapts
to the settings of debug and catcherrors.
LzDebug: Document the reporting of errors by the debugger and how
to silence the reports.
build.xml: Build swf10 first, since it has the strictest
compiler, so you don't waste time building other runtimes that
will only be broken.
LzDebugStub, LzBootstrapDebugService: Add a handler for reporting
errors (and eliminating multiple reports). Remove the old
top-level error handler, which is no longer needed.
JavascriptGenerator: Based on compiler.catcherrors, #pragma
"throwsError", and debug, construct an appropriate catch block
that records, reports, and re-throws or not.
Tests:
test/lpp-8222 X debug=true/false X compiler.catcherrors=true/false
X lzr=dhtml/swf9.
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/build.xml
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/build.xml 2009-09-16 13:34:27 UTC (rev
14762)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/build.xml 2009-09-16 19:13:37 UTC (rev
14763)
@@ -161,42 +161,12 @@
var LFCdir = lfc.getProperty("LFCdir") + '/';
importPackage(java.io);
- // build the dhtml lfc if we're supposed to
- if (lfc.getProperty("build.lfc.runtime.dhtml")) {
- var plain = LFCdir + "LFCdhtml.js";
- if (!(new File(plain)).exists()) {
- dobuild(plain, "dhtml", "");
- }
- if (buildDebug) {
- var dest = LFCdir + "LFCdhtml-debug.js";
- if (!(new File(dest)).exists()) {
- // TODO: [2006-06-07 ptw] (LPP-2034) When the LFC is 'clean' of
- // warnings, the options can be changed to simply --debug
- dobuild(dest,
- "dhtml",
- "--option nameFunctions --option disableTrackLines --option
warnGlobalAssignments '-D$debug=true'");
- }
- var dest = LFCdir + "LFCdhtml-backtrace.js";
- if (!(new File(dest)).exists()) {
- // TODO: [2006-06-07 ptw] (LPP-2034) When the LFC is 'clean' of
- // warnings, the options can be changed to simply -g3
- dobuild(dest,
- "dhtml",
- "--option debugBacktrace --option nameFunctions --option
disableTrackLines --option warnGlobalAssignments '-D$debug=true'");
- }
- }
- if (buildProfile) {
- var profile = LFCdir + "LFCdhtml-profile.js";
- if (!(new File(profile)).exists()) {
- dobuild(profile, "dhtml", "--profile");
- }
- }
- }
- var swfruntimes = [7, 8, 9, 10];
+ var swfruntimes = [ 10, 9, 8 ];
- for (var s in swfruntimes) {
- var v = swfruntimes[s];
+ // Build the strictest first, so we fail early
+ for (var i = 0, l = swfruntimes.length; i < l; i++) {
+ var v = swfruntimes[i];
var ext = (v >= 9) ? ".swc" : ".lzl";
var shlibopt = "--option buildSharedLibrary=true ";
@@ -241,6 +211,39 @@
}
}
}
+
+
+ // build the dhtml lfc if we're supposed to
+ if (lfc.getProperty("build.lfc.runtime.dhtml")) {
+ var plain = LFCdir + "LFCdhtml.js";
+ if (!(new File(plain)).exists()) {
+ dobuild(plain, "dhtml", "");
+ }
+ if (buildDebug) {
+ var dest = LFCdir + "LFCdhtml-debug.js";
+ if (!(new File(dest)).exists()) {
+ // TODO: [2006-06-07 ptw] (LPP-2034) When the LFC is 'clean' of
+ // warnings, the options can be changed to simply --debug
+ dobuild(dest,
+ "dhtml",
+ "--option nameFunctions --option disableTrackLines --option
warnGlobalAssignments '-D$debug=true'");
+ }
+ var dest = LFCdir + "LFCdhtml-backtrace.js";
+ if (!(new File(dest)).exists()) {
+ // TODO: [2006-06-07 ptw] (LPP-2034) When the LFC is 'clean' of
+ // warnings, the options can be changed to simply -g3
+ dobuild(dest,
+ "dhtml",
+ "--option debugBacktrace --option nameFunctions --option
disableTrackLines --option warnGlobalAssignments '-D$debug=true'");
+ }
+ }
+ if (buildProfile) {
+ var profile = LFCdir + "LFCdhtml-profile.js";
+ if (!(new File(profile)).exists()) {
+ dobuild(profile, "dhtml", "--profile");
+ }
+ }
+ }
]]> </script>
<ant dir="${schema.dir}" target="lfc.schema" />
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzBootstrapDebugService.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzBootstrapDebugService.lzs
2009-09-16 13:34:27 UTC (rev 14762)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzBootstrapDebugService.lzs
2009-09-16 19:13:37 UTC (rev 14763)
@@ -553,6 +553,17 @@
// debugger bugs reported.
/** @access private */
+var $reportedError = null;
+
+/** @access private */
+function $reportException (fileName, lineNumber, e) {
+ if (e !== $reportedError) {
+ $reportedError = e;
+ $reportSourceWarning(fileName, lineNumber, e.name + ": " + e.message,
true);
+ }
+}
+
+/** @access private */
function $reportUndefinedObjectProperty (filename, lineNumber, propertyName) {
#pragma "warnUndefinedReferences=false"
if (! arguments.callee._dbg_recursive_call) {
@@ -631,27 +642,3 @@
$reportUndefinedMethod._dbg_recursive_call = false;
-if ($js1) {
- /**
- * We can't use evalCarefully everywhere, so we also install a default
- * error handler
- */
- if (typeof window.addEventListener == 'function') {
- // The DOM 1 interface is more useful than the DOM 2 interface
- window.onerror = function (errorString, fileName, lineNo) {
-#pragma "warnUndefinedReferences=false"
- if (Debug.uncaughtBacktraceStack) {
- // If backtracing has caught our stack info, use that rather
- // than browser info
- errorString = new String(errorString);
- errorString.$lzsc$b = Debug.uncaughtBacktraceStack;
- Debug.uncaughtBacktraceStack = null;
- fileName = null;
- lineNo = null;
- }
- $reportSourceWarning(fileName, lineNo, errorString, true);
- // pass through to browser debugger
- return false;
- }
- }
-}
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzDebugStub.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzDebugStub.lzs 2009-09-16
13:34:27 UTC (rev 14762)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/compiler/LzDebugStub.lzs 2009-09-16
19:13:37 UTC (rev 14763)
@@ -44,6 +44,13 @@
}
/**
+ * Avoid reporting the same exception when re-thrown
+ *
+ * @access private
+ */
+ static var reportedError = null;
+
+ /**
* Report an exception to the debug window
*
* @param String fileName: The source file
@@ -53,7 +60,10 @@
* @access private
*/
static function reportException (fileName, lineNumber, e) {
- $reportSourceWarning(fileName, lineNumber, e.name + ": " + e.message,
true);
+ if (e !== reportedError) {
+ reportedError = e;
+ $reportSourceWarning(fileName, lineNumber, e.name + ": " + e.message,
true);
+ }
}
};
} else {
Modified: openlaszlo/trunk/WEB-INF/lps/lfc/debugger/LzDebug.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/debugger/LzDebug.lzs 2009-09-16
13:34:27 UTC (rev 14762)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/debugger/LzDebug.lzs 2009-09-16
19:13:37 UTC (rev 14763)
@@ -86,6 +86,13 @@
* </canvas>]]>
* </programlisting></example>
*
+ * By default, the debugger will intercept runtime errors (instances
+ * of Error that are thrown by the runtime or program) and report
+ * them. These reports can be silenced by throwing values that are
+ * not instances of Error, or by adding <code>#pragma
+ * "throwsErrors=true"</code> to the function or method containing the
+ * throw.
+ *
* <p>The optional <xref linkend="lz.debug"/> tag controls the appearance of
* the debugger console window when debugging is on.</p>
*
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
2009-09-16 13:34:27 UTC (rev 14762)
+++ openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/Compiler.java
2009-09-16 19:13:37 UTC (rev 14763)
@@ -503,11 +503,12 @@
public static String SWF9_APPLICATION_PREAMBLE = "SWF9applicationPreamble";
public static String SWF9_APP_CLASSNAME = "SWF9MainClassName";
public static String SWF9_WRAPPER_CLASSNAME = "SWF9WrapperClassName";
- public static String SWF9_LFC_CLASSNAME = "SWF9LFCClassName";
+ public static String SWF9_LFC_CLASSNAME = "SWF9LFCClassName";
public static String SWF9_LOADABLE_LIB = "SWF9LoadableLib";
public static String SWF9_USE_RUNTIME_SHARED_LIB = "SWF9RuntimeSharedLib";
public static String SWF8_LOADABLE_LIB = "SWF8LoadableLib";
public static String TRACK_LINES = "trackLines";
+ public static String THROWS_ERROR = "throwsError";
public static String VALIDATE_CACHES = "validateCaches";
public static String WARN_UNDEFINED_REFERENCES = "warnUndefinedReferences";
public static String WARN_GLOBAL_ASSIGNMENTS = "warnGlobalAssignments";
Modified:
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
===================================================================
---
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2009-09-16 13:34:27 UTC (rev 14762)
+++
openlaszlo/trunk/WEB-INF/lps/server/src/org/openlaszlo/sc/JavascriptGenerator.java
2009-09-16 19:13:37 UTC (rev 14763)
@@ -1248,11 +1248,21 @@
// put the function end before other annotations
suffix.add(0, (meterFunctionEvent(node, "returns", meterFunctionName)));
}
- // If backtrace or catch-exceptions is on, we create an error
+ // If debug or compiler.catcherrors is on, we create an error
// handler to catch the error and return a type-safe null value
// (to emulate the behavior of as2).
- boolean catchExceptions = (options.getBoolean(Compiler.DEBUG_BACKTRACE) ||
-
options.getBoolean(Compiler.CATCH_FUNCTION_EXCEPTIONS));
+ // Non-errors will simply be re-thrown by the catch logic.
+ boolean catchExceptions =
options.getBoolean(Compiler.CATCH_FUNCTION_EXCEPTIONS);
+ // NOTE: [2009-09-14 ptw] `#pragma "throwsError=true"` can be used
+ // to selectively disable the catching of errors when it is
+ // intentional on the part of the user program, but better
+ // practice would be for user programs to use non-Error object as
+ // the value to be thrown.
+ boolean throwExceptions = options.getBoolean(Compiler.THROWS_ERROR);
+ // If debugging is on and the user has not explicitly declared
+ // their intention to throw an error, report Errors
+ boolean debugExceptions = (options.getBoolean(Compiler.DEBUG) ||
+ options.getBoolean(Compiler.DEBUG_SWF9));
// Analyze local variables (and functions)
VariableAnalyzer analyzer =
new VariableAnalyzer(params,
@@ -1268,21 +1278,38 @@
catchExceptions = analyzer.dereferenced;
}
String tryType = "";
- if (catchExceptions) {
- // If debugging is on, we report the caught error
- if (options.getBoolean(Compiler.DEBUG) ||
options.getBoolean(Compiler.DEBUG_SWF9)) {
- // TODO: [2009-03-20 dda] In DHTML, having trouble successfully
defining
- // the $lzsc$runtime class, so we'll report the warning more directly.
- if (this instanceof SWF9Generator) {
- error.add(parseFragment("$lzsc$runtime.reportException(" +
- ScriptCompiler.quote(filename) + ", " +
- lineno + ", $lzsc$e);"));
- } else {
- error.add(parseFragment("$reportSourceWarning(" +
- ScriptCompiler.quote(filename) + ", " +
- lineno + ", $lzsc$e.name + \": \" +
$lzsc$e.message, true);"));
+ if (catchExceptions || throwExceptions || debugExceptions) {
+ String fragment = "";
+ fragment += "if ($lzsc$e is Error) {";
+ if (throwExceptions) {
+ fragment += " lz.$lzsc$thrownError = $lzsc$e";
+ } else {
+ // Don't process errors declared to be thrown
+ fragment += " if (lz['$lzsc$thrownError'] === $lzsc$e) { throw $lzsc$e;
}";
+ if (debugExceptions) {
+ // TODO: [2009-03-20 dda] In DHTML, having trouble
+ // successfully defining the $lzsc$runtime class, so we'll
+ // report the warning more directly.
+ if (this instanceof SWF9Generator) {
+ fragment += " $lzsc$runtime.reportException(";
+ } else {
+ fragment += " $reportException(";
+ }
+ fragment += ScriptCompiler.quote(filename) + ", " + lineno + ",
$lzsc$e);";
}
}
+ // Only neuter Errors if catcherrors is on
+ if (! catchExceptions) {
+ fragment += "}" +
+ "throw $lzsc$e;";
+ } else {
+ fragment +=
+ "} else {" +
+ " throw $lzsc$e;" +
+ "}";
+ }
+ error.add(parseFragment(fragment));
+
// Currently we only do this for the back-end that enforces types
if (this instanceof SWF9Generator) {
// In either case, we return a type-safe null value that is as
Added: openlaszlo/trunk/test/lpp-8222.lzx
Property changes on: openlaszlo/trunk/test/lpp-8222.lzx
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
_______________________________________________
Laszlo-checkins mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-checkins