簡體   English   中英

當某個延遲部分發生異常時,J2V8的Java應用程序崩潰(例如setTimeout或process.nextTick)

[英]A java application with J2V8 crashes when an exception happened in a some deferred section (e.g. setTimeout or process.nextTick)

我使用了令人驚嘆的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(secod示例)中觸發了中斷,但在第一種情況下,JS異常只是在控制台或跟蹤日志中沒有任何解釋的情況下殺死Java應用程序。

看起來你在javascript代碼中拋出的錯誤正在傳播到java環境中。 鑒於您嘗試執行的js代碼( throw 'Error' ),這是人們期望看到的。 你期望發生什么? 只需捕獲java中的任何異常並適當處理 - 也許通過記錄?

try {
    nodeJS.getRuntime().executeVoidScript("throw 'Error'"); 
}
catch(Exception e) { 
    System.out.println(e.toString()); 
}

這是最好和正確的解決方案。

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

有關更多信息,請參閱nodeJS文檔: 事件:'uncaughtException'

現在我的解決方法是這個腳本。

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM