changeset 75:4b1149d818e8

Exceptions work a bit more securely now.
author Atul Varma <varmaa@toolness.com>
date Thu, 30 Jul 2009 21:50:10 -0700
parents e06376295170
children 4cb89d48b068
files test_pymonkey.py utils.c
diffstat 2 files changed, 30 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/test_pymonkey.py	Wed Jul 29 20:43:46 2009 -0700
+++ b/test_pymonkey.py	Thu Jul 30 21:50:10 2009 -0700
@@ -64,8 +64,6 @@
             cx.evaluate_script,
             obj, 'while (1) {}', '<string>', 1
             )
-        self.assertEqual(self.last_exception.message,
-                         "stop eet!")
 
     def testUndefinedStrIsUndefined(self):
         self.assertEqual(str(pymonkey.undefined),
@@ -171,14 +169,24 @@
         self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'),
                          u"o hai")
 
-    def testJsWrappedPythonFunctionThrowsException(self):
+    def testJsWrappedPythonFunctionThrowsJsException(self):
         def hai2u(cx, this, args):
+            raise pymonkey.error(u"blarg")
+        self.assertRaises(pymonkey.error,
+                          self._evalJsWrappedPyFunc,
+                          hai2u, 'hai2u()')
+        self.assertEqual(self.last_exception.message, u"blarg")
+
+    def testJsWrappedPythonFunctionThrowsPyException(self):
+        thecx = []
+        def hai2u(cx, this, args):
+            thecx.append(cx)
             raise Exception("hello")
         self.assertRaises(pymonkey.error,
                           self._evalJsWrappedPyFunc,
                           hai2u, 'hai2u()')
-        self.assertEqual(self.last_exception.message,
-                         "hello")
+        exc = thecx[0].get_object_private(self.last_exception.message)
+        self.assertEqual(exc.message, "hello")
 
     def testJsWrappedPythonFunctionReturnsNone(self):
         def hai2u(cx, this, args):
--- a/utils.c	Wed Jul 29 20:43:46 2009 -0700
+++ b/utils.c	Thu Jul 30 21:50:10 2009 -0700
@@ -177,18 +177,27 @@
   PyObject *traceback;
 
   PyErr_Fetch(&type, &value, &traceback);
-  PyObject *str = PyObject_Unicode(value);
-  if (str == NULL)
-    JS_ReportError(context->cx, "Python exception occurred");
-  else {
+
+  if (type == PYM_error && value &&
+      PyObject_HasAttrString(value, "message")) {
     jsval val;
-    if (PYM_pyObjectToJsval(context, str, &val) == 0) {
-      // TODO: Wrap Python traceback info in JS exception so the client
-      // can examine it.
+    PyObject *message = PyObject_GetAttrString(value, "message");
+    if (message && PYM_pyObjectToJsval(context, message, &val) == 0) {
       JS_SetPendingException(context->cx, val);
     } else
+      JS_ReportError(context->cx,
+                     "Python exception occurred, but exception "
+                     "couldn't be converted");
+    Py_XDECREF(message);
+  } else {
+    if (value) {
+      JSObject *exception = PYM_JS_newObject(context->cx, value);
+      if (exception)
+        JS_SetPendingException(context->cx, OBJECT_TO_JSVAL(exception));
+      else
+        JS_ReportOutOfMemory(context->cx);
+    } else
       JS_ReportError(context->cx, "Python exception occurred");
-    Py_DECREF(str);
   }
 
   Py_XDECREF(type);