JavaScript でスタック トレースを取得する

Habdul Hazeez 2023年10月12日
  1. JavaScript でエラー オブジェクトを使用してスタック トレースを取得する
  2. JavaScript で Console.trace() を使用してスタック トレースを取得する
  3. JavaScript のカスタム関数を使用してスタック トレースを取得する
  4. JavaScript で StackTrace.js を使用してスタック トレースを取得する
JavaScript でスタック トレースを取得する

この記事では、次の方法を使用して JavaScript でスタック トレースを取得する方法について説明します。

  1. エラー オブジェクトでスタック トレースを取得する
  2. console.trace() でスタックトレースを取得
  3. カスタム関数でスタック トレースを取得する
  4. StackTrace.js でスタック トレースを取得する

JavaScript でエラー オブジェクトを使用してスタック トレースを取得する

JavaScript エラー オブジェクトの stack プロパティを使用すると、スタック トレースを取得できます。 ただし、Error コンストラクターを使用してエラー オブジェクトを作成する必要があります。

したがって、コードでエラーが発生した場合は、エラー オブジェクトを作成します。 その結果、スタック トレースを出力できます。

たとえば、以下のコードには、2つの数値を加算する関数 add_num があります。 一方、add_num には、関数の引数が数値であることを検証する条件チェックがあります。

したがって、チェックが失敗した場合は、Error コンストラクターからエラー オブジェクトを作成します。 次に、stack プロパティを使用してスタック トレースを出力します。

したがって、テストとして add_num 関数の 2 番目の引数として文字列を指定しました。 そのため、コードを実行するとスタック トレースが取得されます。

コード例:

function add_num(first_number, second_number) {
  if (typeof (first_number) !== 'number' ||
      typeof (second_number) !== 'number') {
    var error = new Error();
    console.log(error.stack);
  } else {
    console.log(first_number + second_number);
  }
}

let a = 23;
let b = '23';

add_num(a, b);

出力:

add_num@http://localhost/stacktrace/stacktrace-1.html:11:17
@http://localhost/stacktrace/stacktrace-1.html:21:10
stacktrace-1.html:12:13

さらに、コードを try-catch ブロックでラップすることもできます。 したがって、エラーを引き起こす可能性のあるコードを try ブロックに配置し、catch ブロックからスタック トレースを取得します。

try ブロックでエラーが発生した場合、例外変数にアクセスできます。 この例外変数には stack プロパティがあります。

コード例:

try {
  let a = 23;
  console.log(a - b); /* Variable b is not defined, so we get an error */
} catch (e) {
  console.log(e.stack)
}

出力:

@http://localhost/stacktrace/stacktrace-1.html:11:4
stacktrace-1.html:13:12

JavaScript で Console.trace() を使用してスタック トレースを取得する

コンソール オブジェクトには、スタック トレースを Web コンソールに出力するための trace() 関数が含まれています。 したがって、エラーが発生したコードのセクションに console.trace() を配置できます。

以下の例は、前述の add_num 関数です。 ただし、console.trace() 関数を使用するように変更しました。

したがって、無効な引数を指定して add_num 関数を呼び出して、スタック トレースを出力できます。 add_num 関数は数値のみを許可するため、無効な引数は文字列です。 それ以外はエラーになります。

コード例:

function add_num(first_number, second_number) {
  if (typeof (first_number) !== 'number' ||
      typeof (second_number) !== 'number') {
    console.trace();
  } else {
    console.log(first_number + second_number);
  }
}

let a = 23;
let b = '23';

add_num(a, b);

出力:

console.trace() stacktrace-2.html:11:13
    add_num http://localhost/stacktrace/stacktrace-2.html:11
    <anonymous> http://localhost/stacktrace/stacktrace-2.html:20

一方、エラーが発生したときに console.trace() を使用することに限定されません。 これは、コード実行を出力するために使用できることを意味します。

したがって、以下の例では、console.trace() を使用して、add_num のさまざまな実行をトレースします。

コード例:

function add_numbers(a, b) {
  console.trace('You called add_numbers with', a, 'and', b);
  return a + b;
}

function calculate_it() {
  let f = add_numbers(42, 9);
  let j = add_numbers(0, 0);
  return f + j;
}

function start_the_trace() {
  let a = add_numbers(12, 33);
  let b = calculate_it();
}

start_the_trace();

出力:

console.trace() You called add_numbers with 12 and 33 stacktrace-2.html:10:12
    add_numbers http://localhost/stacktrace/stacktrace-2.html:10
    start_the_trace http://localhost/stacktrace/stacktrace-2.html:21
    <anonymous> http://localhost/stacktrace/stacktrace-2.html:25
console.trace() You called add_numbers with 42 and 9 stacktrace-2.html:10:12
    add_numbers http://localhost/stacktrace/stacktrace-2.html:10
    calculate_it http://localhost/stacktrace/stacktrace-2.html:15
    start_the_trace http://localhost/stacktrace/stacktrace-2.html:22
    <anonymous> http://localhost/stacktrace/stacktrace-2.html:25
console.trace() You called add_numbers with 0 and 0 stacktrace-2.html:10:12
    add_numbers http://localhost/stacktrace/stacktrace-2.html:10
    calculate_it http://localhost/stacktrace/stacktrace-2.html:16
    start_the_trace http://localhost/stacktrace/stacktrace-2.html:22
    <anonymous> http://localhost/stacktrace/stacktrace-2.html:25

JavaScript のカスタム関数を使用してスタック トレースを取得する

エラーが発生したときにスタック トレースを生成するカスタム関数を定義できます。 また、コード内でエラーが発生する場所に関数を配置する必要があります。

一方、関数は、コード内のエラーが関数の実行でエラーを引き起こすように機能します。 したがって、スタック トレースと、それが関数に影響を与えた場所を確認できます。

次のコードには、エラーが発生したときにスタック トレースを生成するカスタム関数があります。 そのため、Web ブラウザー コンソールでスタック トレースを確認します。

コード例:

function stack_trace() {
  function st2(f) {
    let split_string = f.toString().split('(')[0].substring(9);
    let join_string = f.arguments.join(',');
    return !f ? [] :
                st2(f.caller).concat([split_string + '(' + join_string + ')']);
  }
  return st2(arguments.callee.caller);
}

function add_num(first_number, second_number) {
  if (typeof (first_number) !== 'number' ||
      typeof (second_number) !== 'number') {
    stack_trace();
  } else {
    console.log(first_number + second_number);
  }
}

let a = 23;
let b = '23';

add_num(a, b);

出力:

Uncaught TypeError: f.arguments.join is not a function
    st2 http://localhost/stacktrace/stacktrace-3.html:12
    stack_trace http://localhost/stacktrace/stacktrace-3.html:16
    add_num http://localhost/stacktrace/stacktrace-3.html:21
    <anonymous> http://localhost/stacktrace/stacktrace-3.html:30
stacktrace-3.html:12:35

JavaScript で StackTrace.js を使用してスタック トレースを取得する

StackTrace.js は、コード内のスタック トレースを取得するために使用できる JavaScript ライブラリです。 まず、StackTrace.js ではコールバック関数を定義する必要があります。

このコールバック関数は、スタック トレースを Web ブラウザ コンソールに出力します。 一方、裏では StackTrace.js は Error.stackstack プロパティを使用しています。

次のコードでは、CDNJS から StackTrace.js をインポートしました。 そのため、コールバック関数をアロー関数として定義し、add_num 関数を再作成しました。

ただし、add_num 関数は StackTrace.js を使用してスタック トレースを出力します。

コード例:

<head>
    <meta charset="utf-8" />
    <title>Stacktrace-4</title>
    <script
        src="https://cdnjs.cloudflare.com/ajax/libs/stacktrace.js/2.0.2/stacktrace.min.js"
        integrity="sha512-9fotp9F7mNA1AztobpB07lScgCKiN4i2JuRYTl8MxiHQVJs05EJqeUfPWt9OFAKD1QsIVZiNFQSdov9luOT8TA=="
        crossorigin="anonymous"
        referrerpolicy="no-referrer">
    </script>
</head>
<body>
    <script>
        var callback = function (stack_frames) {
            var stringified_stack = stack_frames.map((the_stack_frame) => {
                return the_stack_frame.toString();
            }).join('\n');
            console.log(stringified_stack);
        };

        function addNum(n1, n2) {
            if (typeof(n1) !== "number" || typeof(n2) !== "number") {
                StackTrace.get().then(callback);
            } else {
                console.log(n1 + n2);
            }
        }

        let a = 23;
        let b = "23";
        addNum(a, b);
    </script>
</body>

出力:

_generateError (https://cdnjs.cloudflare.com/ajax/libs/stacktrace.js/2.0.2/stacktrace.js:28:)
get (https://cdnjs.cloudflare.com/ajax/libs/stacktrace.js/2.0.2/stacktrace.js:77:)
addNum (http://localhost/stacktrace/stacktrace-4.html:24:16)
http://localhost/stacktrace/stacktrace-4.html:32:9 stacktrace-4.html:19:12
著者: Habdul Hazeez
Habdul Hazeez avatar Habdul Hazeez avatar

Habdul Hazeez is a technical writer with amazing research skills. He can connect the dots, and make sense of data that are scattered across different media.

LinkedIn