3

我使用了令人惊叹的J2V8 java 库,它允许在您的 Java 应用程序中执行任何 Javascript 代码,此外它还可以集成 nodeJS 引擎。

但我遇到了下一个问题。此代码在 nodejs 调用 setTimeout 的回调函数后立即中断 Java 应用程序,尽管存在 try..carch 块,但该函数抛出异常。异常甚至没有进入 try..catch 块。

// It is an example, in real case it can be a some erorr in a code.
nodeJS = NodeJS.createNodeJS();
try {
    nodeJS.getRuntime().executeVoidScript("setTimeout(function(){throw 'Error'}, 1000);"); 
} catch (Exception e) {
    e.printStackTrace();
}

应用程序被以下消息中断:

undefined:1
setTimeout(function(){throw 'Error'}, 10000);
                  ^
Error
Process finished with exit code 1

另一个例子表明,异常并不总是导致应用程序中断,它是一种“正常”情况。

nodeJS = NodeJS.createNodeJS();
try {
    nodeJS.getRuntime().executeVoidScript("throw 'Error'");
} catch (Exception e) {
    e.printStackTrace();
}

在这种情况下,我们在控制台中看到唯一的错误消息,但应用程序仍然有效。

Exception in thread "Thread-2" undefined:1: Error
throw 'Error'
^
com.eclipsesource.v8.V8ScriptExecutionException
    at com.eclipsesource.v8.V8._executeScript(Native Method)
    at com.eclipsesource.v8.V8.executeScript(V8.java:940)
    at com.eclipsesource.v8.V8.executeScript(V8.java:595)
    at com.eclipsesource.v8.V8.executeObjectScript(V8.java:625)
    at com.eclipsesource.v8.V8.executeObjectScript(V8.java:608)
    at org.efc.origamiapp.v8.V8Environment.run(V8Environment.java:383)

上面的示例在 try..catch 块中,您可以在其下方看到跟踪堆栈。所以中断是在 Native Method 中触发的(第二个示例),但在第一种情况下,JS 异常只是杀死了 Java 应用程序,而在控制台或跟踪日志中没有任何解释。

4

3 回答 3

1

看起来您在 javascript 代码中抛出的错误正在传播到 java 环境中。考虑到您尝试执行的 js 代码(),这是人们期望看到的throw 'Error'。你期望会发生什么?只需在 java 中捕获任何异常并适当处理 - 也许通过日志记录?

try {
    nodeJS.getRuntime().executeVoidScript("throw 'Error'"); 
}
catch(Exception e) { 
    System.out.println(e.toString()); 
}
于 2016-10-15T10:54:35.737 回答
1

这是最好和正确的解决方案。

process.on('unhandledRejection', (err) => {
    console.error('Unhandled promise rejection',err);
});
process.on('uncaughtException', (err) => {
    console.error('Uncaught exception',err);
});

有关更多信息,请参阅 nodeJS 文档:事件:'uncaughtException'

于 2017-04-01T07:29:51.003 回答
0

现在我的解决方法是这个脚本。

let nativeSetTimeout = setTimeout;
setTimeout = function(fn, t){
    let safeFn = () => {
        try {
            fn();
        } catch(e){
            console.log(e);
        }
    };
    return nativeSetTimeout(safeFn,t);
} 


let nativeNextTick = process.nextTick;
process.nextTick = function(){
    let args = Array.prototype.slice.call(arguments);
    let fn = args[0];
    let safeFn = () => {
        try {
            fn.apply(null,args.slice(1));
        } catch(e){
            console.log(e);
        }
    };
    return nativeNextTick(safeFn);
}

我在应用程序的开头调用此脚本。

nodeJS.getRuntime().executeVoidScript(workaroundScript);
于 2016-10-15T11:41:02.063 回答