浏览代码

Merge remote-tracking branch 'stesie/require-exception-handling' into php7

Stefan Siegl 7 年之前
父节点
当前提交
b12a2fb4e3
共有 3 个文件被更改,包括 90 次插入6 次删除
  1. 35 0
      tests/commonjs_exception_001.phpt
  2. 38 0
      tests/commonjs_exception_002.phpt
  3. 17 6
      v8js_methods.cc

+ 35 - 0
tests/commonjs_exception_001.phpt

@@ -0,0 +1,35 @@
+--TEST--
+Test V8Js::setModuleLoader : Forward exceptions
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$JS = <<< EOT
+var foo = require("./test");
+EOT;
+
+$v8 = new V8Js();
+$v8->setModuleLoader(function($module) {
+    throw new Exception('some exception');
+});
+
+$v8->executeString($JS, 'module.js', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS);
+?>
+===EOF===
+--EXPECTF--
+Fatal error: Uncaught Exception: some exception in %s%ecommonjs_exception_001.php:9
+Stack trace:
+#0 [internal function]: {closure}('test')
+#1 %s%ecommonjs_exception_001.php(12): V8Js->executeString('var foo = requi...', 'module.js', 4)
+#2 {main}
+
+Next V8JsScriptException: module.js:1: Exception: some exception in %s%ecommonjs_exception_001.php:9
+Stack trace:
+#0 [internal function]: {closure}('test')
+#1 %s%ecommonjs_exception_001.php(12): V8Js->executeString('var foo = requi...', 'module.js', 4)
+#2 {main} in %s%ecommonjs_exception_001.php:12
+Stack trace:
+#0 %s%ecommonjs_exception_001.php(12): V8Js->executeString('var foo = requi...', 'module.js', 4)
+#1 {main}
+  thrown in %s%ecommonjs_exception_001.php on line 12

+ 38 - 0
tests/commonjs_exception_002.phpt

@@ -0,0 +1,38 @@
+--TEST--
+Test V8Js::setModuleNormaliser : Forward exceptions
+--SKIPIF--
+<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
+--FILE--
+<?php
+
+$JS = <<< EOT
+var foo = require("./test");
+EOT;
+
+$v8 = new V8Js();
+$v8->setModuleNormaliser(function($module) {
+    throw new Exception('some exception');
+});
+$v8->setModuleLoader(function($module) {
+	echo 'dummy ...';
+});
+
+$v8->executeString($JS, 'module.js', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS);
+?>
+===EOF===
+--EXPECTF--
+Fatal error: Uncaught Exception: some exception in %s%ecommonjs_exception_002.php:9
+Stack trace:
+#0 [internal function]: {closure}('', './test')
+#1 %s%ecommonjs_exception_002.php(15): V8Js->executeString('var foo = requi...', 'module.js', 4)
+#2 {main}
+
+Next V8JsScriptException: module.js:1: Exception: some exception in %s%ecommonjs_exception_002.php:9
+Stack trace:
+#0 [internal function]: {closure}('', './test')
+#1 %s%ecommonjs_exception_002.php(15): V8Js->executeString('var foo = requi...', 'module.js', 4)
+#2 {main} in %s%ecommonjs_exception_002.php:15
+Stack trace:
+#0 %s%ecommonjs_exception_002.php(15): V8Js->executeString('var foo = requi...', 'module.js', 4)
+#1 {main}
+  thrown in %s%ecommonjs_exception_002.php on line 15

+ 17 - 6
v8js_methods.cc

@@ -267,9 +267,14 @@ V8JS_METHOD(require)
 
 		// Check if an exception was thrown
 		if (EG(exception)) {
-			// Clear the PHP exception and throw it in V8 instead
-			zend_clear_exception();
-			info.GetReturnValue().Set(isolate->ThrowException(V8JS_SYM("Module normaliser callback exception")));
+			if (c->flags & V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS) {
+				zval tmp_zv;
+				ZVAL_OBJ(&tmp_zv, EG(exception));
+				info.GetReturnValue().Set(isolate->ThrowException(zval_to_v8js(&tmp_zv, isolate)));
+				zend_clear_exception();
+			} else {
+				v8js_terminate_execution(isolate);
+			}
 			return;
 		}
 
@@ -389,9 +394,15 @@ V8JS_METHOD(require)
 		efree(normalised_module_id);
 		efree(normalised_path);
 
-		// Clear the PHP exception and throw it in V8 instead
-		zend_clear_exception();
-		info.GetReturnValue().Set(isolate->ThrowException(V8JS_SYM("Module loader callback exception")));
+		if (c->flags & V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS) {
+			zval tmp_zv;
+			ZVAL_OBJ(&tmp_zv, EG(exception));
+			info.GetReturnValue().Set(isolate->ThrowException(zval_to_v8js(&tmp_zv, isolate)));
+			zend_clear_exception();
+		} else {
+			v8js_terminate_execution(isolate);
+		}
+
 		return;
 	}