Skip to content

Commit b706a85

Browse files
authored
Allow stacktraces in Lua 5.1 and LuaJIT and fix level in lualib (#1610)
* Allow stacktraces in Lua 5.1 and LuaJIT * Fix the constructor passed when getting the stacktrace * Fix testEachVersion builder * Fix lint * Run prettier
1 parent e2e7578 commit b706a85

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

src/lualib/Error.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { __TS__New } from "./New";
2+
13
interface ErrorType {
24
name: string;
35
new (...args: any[]): Error;
@@ -22,6 +24,11 @@ function getErrorStack(constructor: () => any): string | undefined {
2224

2325
if (_VERSION.includes("Lua 5.0")) {
2426
return debug.traceback(`[Level ${level}]`);
27+
// @ts-ignore Fails when compiled with Lua 5.0 types
28+
} else if (_VERSION === "Lua 5.1") {
29+
// Lua 5.1 and LuaJIT have a bug where it's not possible to specify the level without a message.
30+
// @ts-ignore Fails when compiled with Lua 5.0 types
31+
return string.sub(debug.traceback("", level), 2);
2532
} else {
2633
// @ts-ignore Fails when compiled with Lua 5.0 types
2734
return debug.traceback(undefined, level);
@@ -33,7 +40,7 @@ function wrapErrorToString<T extends Error>(getDescription: (this: T) => string)
3340
const description = getDescription.call(this as T);
3441
const caller = debug.getinfo(3, "f");
3542
// @ts-ignore Fails when compiled with Lua 5.0 types
36-
const isClassicLua = _VERSION.includes("Lua 5.0") || _VERSION === "Lua 5.1";
43+
const isClassicLua = _VERSION.includes("Lua 5.0");
3744
if (isClassicLua || (caller && caller.func !== error)) {
3845
return description;
3946
} else {
@@ -55,7 +62,7 @@ export const Error: ErrorConstructor = initErrorClass(
5562
public stack?: string;
5663

5764
constructor(public message = "") {
58-
this.stack = getErrorStack((this.constructor as any).new);
65+
this.stack = getErrorStack(__TS__New as any);
5966
const metatable = getmetatable(this);
6067
if (metatable && !metatable.__errorToStringPatched) {
6168
metatable.__errorToStringPatched = true;

test/unit/error.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as util from "../util";
2+
import * as tstl from "../../src";
23

34
test("throwString", () => {
45
util.testFunction`
@@ -343,3 +344,27 @@ test("still works without debug module", () => {
343344
stack: undefined,
344345
});
345346
});
347+
348+
util.testEachVersion(
349+
"error stacktrace omits constructor and __TS_New",
350+
() => util.testFunction`
351+
const e = new Error();
352+
return e.stack;
353+
`,
354+
{
355+
...util.expectEachVersionExceptJit(builder => {
356+
builder.expectToHaveNoDiagnostics();
357+
const luaResult = builder.getLuaExecutionResult();
358+
// eslint-disable-next-line jest/no-standalone-expect
359+
expect(luaResult.split("\n")).toHaveLength(4);
360+
}),
361+
362+
// 5.0 debug.traceback doesn't support levels
363+
[tstl.LuaTarget.Lua50](builder) {
364+
builder.expectToHaveNoDiagnostics();
365+
const luaResult = builder.getLuaExecutionResult();
366+
// eslint-disable-next-line jest/no-standalone-expect
367+
expect(luaResult).toContain("Level 4");
368+
},
369+
}
370+
);

test/util.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; l
4343
return { lauxlib, lua, lualib };
4444
}
4545
if (target === tstl.LuaTarget.LuaJIT) {
46-
throw Error("Can't use executeLua() or expectToMatchJsResult() wit LuaJIT as target!");
46+
throw Error("Can't use executeLua() or expectToMatchJsResult() with LuaJIT as target!");
4747
}
4848

4949
const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.54");
@@ -63,7 +63,7 @@ export function testEachVersion<T extends TestBuilder>(
6363
): void {
6464
for (const version of Object.values(tstl.LuaTarget) as tstl.LuaTarget[]) {
6565
const specialBuilder = special?.[version];
66-
if (specialBuilder === false) return;
66+
if (specialBuilder === false) continue;
6767

6868
const testName = name === undefined ? version : `${name} [${version}]`;
6969
defineTest(testName, () => {

0 commit comments

Comments
 (0)