Vm2: サンドボックス内のエラーの「正しい」スタックトレースのサポートを追加します

作成日 2017年08月05日  ·  13コメント  ·  ソース: patriksimek/vm2

サンドボックスからエラーがスローされたときに、vm2が「正しい」スタックトレースを表示できれば便利です。

たとえば、これは現在表示されているものです。

/home/user/box-js/node_modules/vm2/lib/main.js:213
                        throw this._internal.Decontextify.value(e);
                        ^

Error: foobar
    at Object.log (/home/user/box-js/analyze.js:248:10)
    at Object.apply (/home/user/box-js/node_modules/vm2/lib/contextify.js:288:34)
    at vm.js:491:9
    at ContextifyScript.Script.runInContext (vm.js:53:29)
    at VM.run (/home/user/box-js/node_modules/vm2/lib/main.js:207:72)
    at Object.<anonymous> (/home/user/box-js/analyze.js:383:5)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)

エラーをスローした関数の呼び出しに(サンドボックスコード内の)どの行が原因であるかを把握する方法はありますか?

feature request help wanted

最も参考になるコメント

この問題を購読している人々に通知するためにコメントを残すだけです-私はPRを開いたので、そこで進行状況を追跡することができます。

全てのコメント13件

これは素晴らしいでしょう。 私は今、コーディングの間違いを突き止めようとしていて、行番号なしでひどく苦労しています

安全であることがわかっているテストケースを実行している場合は、一時的にvm2をネイティブvmに置き換えて、エラーを追跡できます。

この機能も欲しいです。 誰かが私を正しい方向に向けたら、それを書くためにピッチインして幸せです。

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

APIの非互換性があるため、vm2をネイティブvmに置き換えるのは簡単ではないことがわかりました。これが開いたままになることを願っています!

@patriksimek 、私は例外パーサー/

const StackTracey = require ('stacktracey');
const { VM } = require('vm2');

const sourceCode = `function f() {
    throw Exception('e');
}
f();`;
const scriptName = "hello_world.js";

process.on("uncaughtException",  e => {
    if (!e.stack.includes("/node_modules/vm2/")) {
        // This is not a vm2 error, so print it normally
        console.log(e);
        return;
    }
    const oldStack = new StackTracey(e);
    const newStack = [];
    for (const line of oldStack) {
        // Discard internal code
        if (line.file.includes("/cjs"))
            continue;
        if (line.thirdParty && line.file.includes("/node_modules/vm2/"))
            continue;
        if (line.callee == "Script.runInContext")
            continue;
        // Replace the default filename with the user-provided one
        if (line.fileName == "vm.js")
            line.fileRelative = line.fileShort = line.fileName = scriptName;
        newStack.push(line);
    }
    console.log("[vm2] A clean stack trace follows:");
    console.log(new StackTracey(newStack).pretty);
});

const vm = new VM();
vm.run(sourceCode, scriptName);

上記のコードは次のように出力されます。

ReferenceError: Exception is not defined
    at f (vm.js:2:2)
    at vm.js:4:1
    at Script.runInContext (vm.js:135:20)
    at VM.run (/tmp/vm2-test/node_modules/vm2/lib/main.js:210:72)
    at Object.<anonymous> (/tmp/vm2-test/index.js:33:4)
    at Module._compile (internal/modules/cjs/loader.js:805:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:816:10)
    at Module.load (internal/modules/cjs/loader.js:672:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:612:12)
    at Function.Module._load (internal/modules/cjs/loader.js:604:3)
[vm2] A clean stack trace follows:
at f            hello_world.js:2
at              hello_world.js:4
at <anonymous>  index.js:33       vm.run(sourceCode, scriptName);

このライブラリをテストする機会はありませんでしたが、最近vmモジュールを使用し、新しいvm.Scriptを作成するときに適切なラインオフセットを設定することで、正確なスタックトレース番号を実現しました。

この問題は、最近のアクティビティがないため、自動的に古いものとしてマークされています。 それ以上のアクティビティが発生しない場合は閉じられます。 貢献していただきありがとうございます。

この問題と提案はまだ私に関連しているので、コメントしたいと思いました!

私にも非常に関連しています。

@patriksimek @CapacitorSetの実装またはそれらの線に沿った何かをプロジェクトに統合できますか?
ありがとう。

パトリック、実装スケッチは全体的に問題ないように見えますか? もしそうなら、私はPRをすることができ、そこから仕事をすることができます。

@CapacitorSetはい、PRを確認させていただきます。 いくつかの注意:

  • vm.runメソッドは2番目のパラメーターを受け入れません。そのため、スクリプト名は無視されます。 現在、最初に指定した名前でVMScriptを作成する必要があります。 しかし、それは簡単に改善できます。
  • 外部ライブラリの使用を回避する方法はありますか? ゼロデップに固執するのがいいでしょう。

この問題を購読している人々に通知するためにコメントを残すだけです-私はPRを開いたので、そこで進行状況を追跡することができます。

このページは役に立ちましたか?
0 / 5 - 0 評価