Bug 690552. ScratchPad should display exceptions as comments, just as it does for results. r=felipe,robcee
authorKenny Heaton <kennyheaton@gmail.com>
Tue, 03 Jan 2012 08:53:39 -0800
changeset 85021 8c43976e73a452516bd687583e7e4a5fb74855f3
parent 84896 a737cc816eeccdb145f4d73043d02a2d4f79c5aa
child 85022 50c9e7757aa5a045a998fa27f6ae27d7744f3ebc
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe, robcee
bugs690552
milestone12.0a1
Bug 690552. ScratchPad should display exceptions as comments, just as it does for results. r=felipe,robcee
browser/devtools/scratchpad/scratchpad.js
browser/devtools/scratchpad/test/Makefile.in
browser/devtools/scratchpad/test/browser_scratchpad_bug690552_display_outputs_errors.js
--- a/browser/devtools/scratchpad/scratchpad.js
+++ b/browser/devtools/scratchpad/scratchpad.js
@@ -327,31 +327,17 @@ var Scratchpad = {
   evalInContentSandbox: function SP_evalInContentSandbox(aString)
   {
     let error, result;
     try {
       result = Cu.evalInSandbox(aString, this.contentSandbox, "1.8",
                                 "Scratchpad", 1);
     }
     catch (ex) {
-      this.openWebConsole();
-
-      let contentWindow = this.gBrowser.selectedBrowser.contentWindow;
-
-      let scriptError = Cc["@mozilla.org/scripterror;1"].
-                        createInstance(Ci.nsIScriptError);
-
-      scriptError.initWithWindowID(ex.message + "\n" + ex.stack, ex.fileName,
-                                   "", ex.lineNumber, 0, scriptError.errorFlag,
-                                   "content javascript",
-                                   this.getInnerWindowId(contentWindow));
-
-      Services.console.logMessage(scriptError);
-
-      error = true;
+      error = ex;
     }
 
     return [error, result];
   },
 
   /**
    * Evaluate a string in the most recent navigator:browser chrome window.
    *
@@ -363,21 +349,17 @@ var Scratchpad = {
   evalInChromeSandbox: function SP_evalInChromeSandbox(aString)
   {
     let error, result;
     try {
       result = Cu.evalInSandbox(aString, this.chromeSandbox, "1.8",
                                 "Scratchpad", 1);
     }
     catch (ex) {
-      Cu.reportError(ex);
-      Cu.reportError(ex.stack);
-      this.openErrorConsole();
-
-      error = true;
+      error = ex;
     }
 
     return [error, result];
   },
 
   /**
    * Evaluate a string in the currently desired context, that is either the
    * chrome window or the tab content window object.
@@ -392,66 +374,110 @@ var Scratchpad = {
     return this.executionContext == SCRATCHPAD_CONTEXT_CONTENT ?
            this.evalInContentSandbox(aString) :
            this.evalInChromeSandbox(aString);
   },
 
   /**
    * Execute the selected text (if any) or the entire editor content in the
    * current context.
+   * @return mixed
+   *         The script evaluation result.
+   */
+  execute: function SP_execute()
+  {
+    let selection = this.selectedText || this.getText();
+    let [error, result] = this.evalForContext(selection);
+    return [selection, error, result];
+  },
+
+  /**
+   * Execute the selected text (if any) or the entire editor content in the
+   * current context.
    */
   run: function SP_run()
   {
-    let selection = this.selectedText || this.getText();
-    let [error, result] = this.evalForContext(selection);
-    this.deselect();
+    let [selection, error, result] = this.execute();
+
+    if (!error) {
+      this.deselect();
+    } else {
+      this.writeAsErrorComment(error);
+    }
+
     return [selection, error, result];
   },
 
   /**
    * Execute the selected text (if any) or the entire editor content in the
    * current context. The resulting object is opened up in the Property Panel
    * for inspection.
    */
   inspect: function SP_inspect()
   {
-    let [selection, error, result] = this.run();
+    let [selection, error, result] = this.execute();
 
     if (!error) {
+      this.deselect();
       this.openPropertyPanel(selection, result);
+    } else {
+      this.writeAsErrorComment(error);
     }
   },
 
   /**
    * Execute the selected text (if any) or the entire editor content in the
    * current context. The evaluation result is inserted into the editor after
    * the selected text, or at the end of the editor content if there is no
    * selected text.
    */
   display: function SP_display()
   {
+    let [selectedText, error, result] = this.execute();
+
+    if (!error) {
+      this.writeAsComment(result);
+    } else {
+      this.writeAsErrorComment(error);
+    }
+  },
+
+  /**
+   * Write out a value at the current insertion point as a block comment
+   * @param object aValue
+   *        The Object to write out as a string
+   */
+  writeAsComment: function SP_writeAsComment(aValue)
+  {
     let selection = this.getSelectionRange();
     let insertionPoint = selection.start != selection.end ?
                          selection.end : // after selected text
                          this.editor.getCharCount(); // after text end
-
-    let [selectedText, error, result] = this.run();
-    if (error) {
-      return;
-    }
-
-    let newComment = "/*\n" + result + "\n*/";
-
+                         
+    let newComment = "/*\n" + aValue + "\n*/";
+    
     this.setText(newComment, insertionPoint, insertionPoint);
 
     // Select the new comment.
     this.selectRange(insertionPoint, insertionPoint + newComment.length);
   },
 
   /**
+   * Write out an error at the current insertion point as a block comment
+   * @param object aValue
+   *        The Error object to write out the message and stack trace
+   */
+  writeAsErrorComment: function SP_writeAsErrorComment(aError)
+  {
+    let newComment = "Exception: " + aError.message + "\n" + aError.stack.substring(0, aError.stack.length - 1);
+    
+    this.writeAsComment(newComment);
+  },
+
+  /**
    * Open the Property Panel to inspect the given object.
    *
    * @param string aEvalString
    *        The string that was evaluated. This is re-used when the user updates
    *        the properties list, by clicking the Update button.
    * @param object aOutputObject
    *        The object to inspect, which is the aEvalString evaluation result.
    * @return object
--- a/browser/devtools/scratchpad/test/Makefile.in
+++ b/browser/devtools/scratchpad/test/Makefile.in
@@ -56,11 +56,12 @@ include $(topsrcdir)/config/rules.mk
 		browser_scratchpad_open.js \
 		browser_scratchpad_restore.js \
 		browser_scratchpad_bug_679467_falsy.js \
 		browser_scratchpad_bug_699130_edit_ui_updates.js \
 		browser_scratchpad_bug_669612_unsaved.js \
 		head.js \
 		browser_scratchpad_bug_653427_confirm_close.js \
 		browser_scratchpad_bug684546_reset_undo.js \
+		browser_scratchpad_bug690552_display_outputs_errors.js \
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug690552_display_outputs_errors.js
@@ -0,0 +1,53 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test()
+{
+  waitForExplicitFinish();
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function browserLoad() {
+    gBrowser.selectedBrowser.removeEventListener("load", browserLoad, true);
+    openScratchpad(runTests, {"state":{"text":""}});
+  }, true);
+
+  content.location = "data:text/html,<p>test that exceptions our output as " +
+      "comments for 'display' and not sent to the console in Scratchpad";
+}
+
+function runTests()
+{
+  scratchpad = gScratchpadWindow.Scratchpad;
+
+  var message = "\"Hello World!\""
+  var openComment = "/*\n";
+  var closeComment = "\n*/";
+  var error = "throw new Error(\"Ouch!\")";
+  let messageArray = {};
+  let count = {};
+
+  scratchpad.setText(message);
+  scratchpad.display();
+  is(scratchpad.getText(),
+      message + openComment + "Hello World!" + closeComment,
+      "message display output");
+
+  scratchpad.setText(error);
+  scratchpad.display();
+  is(scratchpad.getText(), 
+      error + openComment + "Exception: Ouch!\n@Scratchpad:1" + closeComment,
+      "error display output");
+
+  scratchpad.setText(message);
+  scratchpad.run();
+  is(scratchpad.getText(), message, "message run output");
+
+  scratchpad.setText(error);
+  scratchpad.run();
+  is(scratchpad.getText(), 
+      error + openComment + "Exception: Ouch!\n@Scratchpad:1" + closeComment,
+      "error display output");
+
+  finish();
+}