diff --git a/tests/commonjs_fatal_error.phpt b/tests/commonjs_fatal_error.phpt new file mode 100644 index 0000000..f246adf --- /dev/null +++ b/tests/commonjs_fatal_error.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test V8Js::setModuleLoader : Handle fatal errors gracefully +--SKIPIF-- + +--FILE-- +setModuleLoader(function() { + trigger_error('some fatal error', E_USER_ERROR); +}); + +$v8->executeString(' require("foo"); '); +?> +===EOF=== +--EXPECTF-- +Fatal error: some fatal error in %s%ecommonjs_fatal_error.php on line 5 diff --git a/v8js_methods.cc b/v8js_methods.cc index 889a707..afa0cd8 100644 --- a/v8js_methods.cc +++ b/v8js_methods.cc @@ -257,13 +257,34 @@ V8JS_METHOD(require) MAKE_STD_ZVAL(normalised_path_zend); ZVAL_STRING(normalised_path_zend, normalised_module_id, 1); - zval **params[1] = {&normalised_path_zend}; - if (FAILURE == call_user_function_ex(EG(function_table), NULL, c->module_loader, &module_code, 1, params, 0, NULL TSRMLS_CC)) { + int call_result; + + zend_try { + { + isolate->Exit(); + v8::Unlocker unlocker(isolate); + + zval **params[1] = {&normalised_path_zend}; + call_result = call_user_function_ex(EG(function_table), NULL, c->module_loader, &module_code, 1, params, 0, NULL TSRMLS_CC); + } + + isolate->Enter(); + + if (call_result == FAILURE) { + info.GetReturnValue().Set(isolate->ThrowException(V8JS_SYM("Module loader callback failed"))); + } + } + zend_catch { + v8js_terminate_execution(isolate); + V8JSG(fatal_error_abort) = 1; + call_result = FAILURE; + } + zend_end_try(); + + if (call_result == FAILURE) { zval_ptr_dtor(&normalised_path_zend); efree(normalised_module_id); efree(normalised_path); - - info.GetReturnValue().Set(isolate->ThrowException(V8JS_SYM("Module loader callback failed"))); return; } zval_ptr_dtor(&normalised_path_zend);