changeset 74:e06376295170

JS exceptions thrown out to Python now include the wrapped original exception. This fixes a TODO.
author Atul Varma <varmaa@toolness.com>
date Wed, 29 Jul 2009 20:43:46 -0700
parents efa0cfe6fc03
children 4b1149d818e8
files test_pymonkey.py utils.c
diffstat 2 files changed, 30 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/test_pymonkey.py	Mon Jul 27 22:00:03 2009 -0700
+++ b/test_pymonkey.py	Wed Jul 29 20:43:46 2009 -0700
@@ -311,9 +311,13 @@
         self.assertRaises(TypeError, pymonkey.undefined)
 
     def testEvaluateThrowsException(self):
+        cx = pymonkey.Runtime().new_context()
+        obj = cx.new_object()
         self.assertRaises(pymonkey.error,
-                          self._evaljs, 'hai2u()')
-        self.assertEqual(self.last_exception.message,
+                          cx.evaluate_script,
+                          obj, 'hai2u()', '<string>', 1)
+        self.assertEqual(self._tostring(cx,
+                                        self.last_exception.message),
                          'ReferenceError: hai2u is not defined')
 
     def testEvaluateReturnsUndefined(self):
@@ -363,6 +367,11 @@
             obj, obj, (1, self)
             )
 
+    def _tostring(self, cx, obj):
+        return cx.call_function(obj,
+                                cx.get_property(obj, u"toString"),
+                                ())
+
     def testCallFunctionRaisesErrorFromJS(self):
         cx = pymonkey.Runtime().new_context()
         obj = cx.new_object()
@@ -374,7 +383,8 @@
         self.assertRaises(pymonkey.error,
                           cx.call_function,
                           obj, obj, (1,))
-        self.assertEqual(self.last_exception.message,
+        self.assertEqual(self._tostring(cx,
+                                        self.last_exception.message),
                          'ReferenceError: blarg is not defined')
 
     def testCallFunctionWorks(self):
--- a/utils.c	Mon Jul 27 22:00:03 2009 -0700
+++ b/utils.c	Wed Jul 29 20:43:46 2009 -0700
@@ -205,19 +205,25 @@
 
   jsval val;
   if (JS_GetPendingException(context->cx, &val)) {
-    JSString *str = NULL;
+    PyObject *obj = PYM_jsvalToPyObject(context, val);
+    if (obj) {
+      PyErr_SetObject(PYM_error, obj);
+      Py_DECREF(obj);
+    } else {
+      PyErr_Clear();
 
-    Py_BEGIN_ALLOW_THREADS;
-    str = JS_ValueToString(context->cx, val);
-    Py_END_ALLOW_THREADS;
+      JSString *str = NULL;
 
-    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
-      PyErr_SetString(PYM_error, "JS exception occurred");
+      Py_BEGIN_ALLOW_THREADS;
+      str = JS_ValueToString(context->cx, val);
+      Py_END_ALLOW_THREADS;
+
+      if (str != NULL) {
+        const char *chars = JS_GetStringBytes(str);
+        PyErr_SetString(PYM_error, chars);
+      } else
+        PyErr_SetString(PYM_error, "JS exception occurred");
+    }
   } else
     PyErr_SetString(PYM_error, "JS_GetPendingException() failed");
 }