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 Error.prototype.stack - JavaScript | MDN, Error reporting · Issue #90 · dop251/goja · GitHub, and How do I get the javascript error trace? · Issue #28 · dop251/goja · GitHub, 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 Emit an errors metric and have a default error rate script abort threshold · Issue #877 · grafana/k6 · GitHub. 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);
};
1 Like