changeset 47:3f4982759e55

Converting JS exceptions into Python exceptions is now doable, albeit not yet implemented, thanks to the discovery of JSOPTION_DONT_REPORT_UNCAUGHT. Also, JS warnings are now converted into Python warnings.
author Atul Varma <varmaa@toolness.com>
date Mon, 06 Jul 2009 08:13:45 -0700
parents a0f677cfc679
children bc4263c6ae82
files context.c runtime.c test_pymonkey.py utils.c
diffstat 4 files changed, 24 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/context.c	Mon Jul 06 01:37:16 2009 -0700
+++ b/context.c	Mon Jul 06 08:13:45 2009 -0700
@@ -3,16 +3,20 @@
 #include "function.h"
 #include "utils.h"
 
-// Default JSErrorReporter for pymonkey-owned JS contexts. We just throw an
-// appropriate exception into Python-space.
 static void
 PYM_reportError(JSContext *cx, const char *message, JSErrorReport *report)
 {
-  if (report->filename)
-    PyErr_Format(PYM_error, "File \"%s\", line %d: %s",
-                 report->filename, report->lineno, message);
-  else
-    PyErr_SetString(PYM_error, message);
+  // Convert JS warnings into Python warnings.
+  if (JSREPORT_IS_WARNING(report->flags)) {
+    if (report->filename)
+      PyErr_WarnExplicit(NULL, message, report->filename, report->lineno,
+                         NULL, NULL);
+    else
+      PyErr_Warn(NULL, message);
+  } else
+    // TODO: Not sure if this will ever get called, but we should know
+    // if it is.
+    PyErr_Warn(NULL, "A JS error was reported.");
 }
 
 static void
--- a/runtime.c	Mon Jul 06 01:37:16 2009 -0700
+++ b/runtime.c	Mon Jul 06 08:13:45 2009 -0700
@@ -61,7 +61,8 @@
     return NULL;
   }
 
-  JS_SetOptions(cx, JSOPTION_VAROBJFIX);
+  JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_DONT_REPORT_UNCAUGHT |
+                JSOPTION_ATLINE | JSOPTION_STRICT);
   JS_SetVersion(cx, JSVERSION_LATEST);
 
   PyObject *retval = (PyObject *) PYM_newJSContextObject(self, cx);
--- a/test_pymonkey.py	Mon Jul 06 01:37:16 2009 -0700
+++ b/test_pymonkey.py	Mon Jul 06 08:13:45 2009 -0700
@@ -57,7 +57,7 @@
                           self._evalJsWrappedPyFunc,
                           hai2u, 'hai2u()')
         self.assertEqual(self.last_exception.message,
-                         "uncaught exception: hello")
+                         "hello")
 
     def testJsWrappedPythonFunctionReturnsNone(self):
         def hai2u(cx):
@@ -127,7 +127,7 @@
         cx = pymonkey.Runtime().new_context()
         obj = cx.new_object()
         cx.init_standard_classes(obj)
-        cx.evaluate_script(obj, 'foo = {bar: 1}', '<string>', 1)
+        cx.evaluate_script(obj, 'var foo = {bar: 1}', '<string>', 1)
         self.assertTrue(isinstance(cx.get_property(obj, u"foo"),
                                    pymonkey.Object))
         self.assertTrue(cx.get_property(obj, u"foo") is
@@ -137,7 +137,7 @@
         cx = pymonkey.Runtime().new_context()
         obj = cx.new_object()
         cx.init_standard_classes(obj)
-        cx.evaluate_script(obj, 'boop = 5', '<string>', 1)
+        cx.evaluate_script(obj, 'var boop = 5', '<string>', 1)
         cx.evaluate_script(obj, 'this["blarg\u2026"] = 5', '<string>', 1)
         self.assertEqual(cx.get_property(obj, u"beans"),
                          pymonkey.undefined)
@@ -181,8 +181,7 @@
         self.assertRaises(pymonkey.error,
                           self._evaljs, 'hai2u()')
         self.assertEqual(self.last_exception.message,
-                         'File "<string>", line 1: ReferenceError: '
-                         'hai2u is not defined')
+                         'ReferenceError: hai2u is not defined')
 
     def testEvaluateReturnsUndefined(self):
         retval = self._evaljs("")
@@ -243,8 +242,7 @@
                           cx.call_function,
                           obj, obj, (1,))
         self.assertEqual(self.last_exception.message,
-                         'File "<string>", line 1: ReferenceError: '
-                         'blarg is not defined')
+                         'ReferenceError: blarg is not defined')
 
     def testCallFunctionWorks(self):
         cx = pymonkey.Runtime().new_context()
--- a/utils.c	Mon Jul 06 01:37:16 2009 -0700
+++ b/utils.c	Mon Jul 06 08:13:45 2009 -0700
@@ -146,10 +146,11 @@
     JS_ReportError(context->cx, "Python exception occurred");
   else {
     jsval val;
-    if (PYM_pyObjectToJsval(context, str, &val) == 0)
-      // TODO: Include filename/line information.
+    if (PYM_pyObjectToJsval(context, str, &val) == 0) {
+      // TODO: Wrap Python traceback info in JS exception so the client
+      // can examine it.
       JS_SetPendingException(context->cx, val);
-    else
+    } else
       JS_ReportError(context->cx, "Python exception occurred");
   }
 
@@ -169,6 +170,8 @@
   if (JS_GetPendingException(context->cx, &val)) {
     JSString *str = JS_ValueToString(context->cx, val);
     if (str != NULL) {
+      // TODO: Wrap the original JS exception so that the client can
+      // examine it.
       const char *chars = JS_GetStringBytes(str);
       PyErr_SetString(PYM_error, chars);
     } else