Просмотр исходного кода

Handle thrown PHP objects, that are no exceptions

Stefan Siegl 9 лет назад
Родитель
Сommit
b7dde1b1db
3 измененных файлов с 88 добавлено и 1 удалено
  1. 43 0
      tests/php_exceptions_005.phpt
  2. 40 0
      tests/php_exceptions_006.phpt
  3. 5 1
      v8js_exceptions.cc

+ 43 - 0
tests/php_exceptions_005.phpt

@@ -0,0 +1,43 @@
+--TEST--
+Test V8::executeString() : PHP Exception handling (JS throw PHP-exception)
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+class Foo {
+    function getException() {
+        return new \Exception("Test-Exception");
+    }
+}
+
+$v8 = new V8Js();
+$v8->foo = new \Foo();
+
+$JS = <<< EOT
+var ex = PHP.foo.getException();
+print("after getException\\n");
+throw ex;
+print("after throw\\n");
+EOT;
+
+try {
+    $v8->executeString($JS, 'php_exceptions_005');
+}
+catch(V8JsScriptException $e) {
+    echo "Got V8JsScriptException\n";
+    var_dump($e->getMessage());
+    var_dump($e->getPrevious()->getMessage());
+}
+?>
+===EOF===
+--EXPECTF--
+after getException
+Got V8JsScriptException
+string(329) "php_exceptions_005:3: exception 'Exception' with message 'Test-Exception' in %s
+Stack trace:
+#0 [internal function]: Foo->getException()
+#1 %s: V8Js->executeString('var ex = PHP.fo...', 'php_exceptions_...')
+#2 {main}"
+string(14) "Test-Exception"
+===EOF===

+ 40 - 0
tests/php_exceptions_006.phpt

@@ -0,0 +1,40 @@
+--TEST--
+Test V8::executeString() : PHP Exception handling (JS throws normal PHP-object)
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+class Foo {
+    function getNonExceptionObject() {
+        return new \Foo();
+    }
+}
+
+$v8 = new V8Js();
+$v8->foo = new \Foo();
+
+$JS = <<< EOT
+var ex = PHP.foo.getNonExceptionObject();
+print("after getNonExceptionObject\\n");
+throw ex;
+print("after throw\\n");
+EOT;
+
+try {
+    $v8->executeString($JS, 'php_exceptions_006');
+}
+catch(V8JsScriptException $e) {
+    echo "Got V8JsScriptException\n";
+    var_dump($e->getMessage());
+    // previous exception should be NULL, as it is *not* a php exception
+    var_dump($e->getPrevious());
+}
+?>
+===EOF===
+--EXPECTF--
+after getNonExceptionObject
+Got V8JsScriptException
+string(34) "php_exceptions_006:3: [object Foo]"
+NULL
+===EOF===

+ 5 - 1
v8js_exceptions.cc

@@ -89,7 +89,11 @@ void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::
 			if(!php_ref.IsEmpty()) {
 				assert(php_ref->IsExternal());
 				zval *php_exception = reinterpret_cast<zval *>(v8::External::Cast(*php_ref)->Value());
-				zend_exception_set_previous(return_value, php_exception TSRMLS_CC);
+
+				zend_class_entry *exception_ce = zend_exception_get_default(TSRMLS_C);
+				if (Z_TYPE_P(php_exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(php_exception), exception_ce TSRMLS_CC)) {
+					zend_exception_set_previous(return_value, php_exception TSRMLS_CC);
+				}
 			}
 		}