Exceptions and e.stack

k6 cloud silently eats unhandled exceptions so I wrap my runs in a try/catch that reports an error rate.

However, it appears re-throwing exceptions or attempting to access e.stack are both broken. So my global exception catcher looses the source of the exception when debugging:

export default function() {
  try {
    throw new Error(`Hey! Where's my stack trace?`);
  } catch (e) {
    console.error(`Unhandled exception`);
    console.log(e);
    console.log(e.stack);
    console.log(JSON.stringify(e));
  }
}

Outputs:

ERRO[0001] Unhandled exception
INFO[0001] Error: Hey! Where's my stack trace?
INFO[0001] undefined
INFO[0001] {}

Judging by https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack, https://github.com/dop251/goja/issues/90, and https://github.com/dop251/goja/issues/28, JS error stack traces are not part of the ECMAScript standard and the goja JS runtime k6 uses doesn’t support them. Unfortunately it seems like the error message is the only thing you can currently rely on :disappointed:

Regarding the k6 cloud eating any errors, we have 2 things on the roadmap - execution logs and https://github.com/loadimpact/k6/issues/877. I can’t give any promises when either of these would be ready, but until they are, here’s a simple workaround you can write with custom metrics:

import { fail, sleep } from "k6";
import { Rate } from "k6/metrics";

let error_rate = new Rate("my_errors");

export let options = {
    vus: 10,
    duration: "1m",
    thresholds: {
        "my_errors": [{ threshold: "rate<0.4", abortOnFail: true }]
    }
};

function actualDefaultFunc() {
    if (Math.random() < 0.2) {
        throw new Error("test");
    }
}

export default function () {
    try {
        actualDefaultFunc();
        error_rate.add(false);
    } catch (e) {
        error_rate.add(true, { error_msg: e.toString() });
    }
    sleep(1);
};