Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/lualib/Error.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { __TS__New } from "./New";

interface ErrorType {
name: string;
new (...args: any[]): Error;
Expand All @@ -22,6 +24,11 @@ function getErrorStack(constructor: () => any): string | undefined {

if (_VERSION.includes("Lua 5.0")) {
return debug.traceback(`[Level ${level}]`);
// @ts-ignore Fails when compiled with Lua 5.0 types
} else if (_VERSION === "Lua 5.1") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guess we should use .includes here too, to trick whatever type nonsense is going on with the version-specific types

Copy link
Contributor Author

@emmachase emmachase Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going by the declaration which only seems to have 5.1, I guess includes is used to catch all of the 5.0 subversions. I think I just need to include another @ts-ignore here. This one is my bad since I changed this last minute without running another build.

declare const _VERSION:
    | ('Lua 5.0' | 'Lua 5.0.1' | 'Lua 5.0.2' | 'Lua 5.0.3')
    | 'Lua 5.1'
    | 'Lua 5.2'
    | 'Lua 5.3'
    | 'Lua 5.4';

// Lua 5.1 and LuaJIT have a bug where it's not possible to specify the level without a message.
// @ts-ignore Fails when compiled with Lua 5.0 types
return string.sub(debug.traceback("", level), 2);
} else {
// @ts-ignore Fails when compiled with Lua 5.0 types
return debug.traceback(undefined, level);
Expand All @@ -33,7 +40,7 @@ function wrapErrorToString<T extends Error>(getDescription: (this: T) => string)
const description = getDescription.call(this as T);
const caller = debug.getinfo(3, "f");
// @ts-ignore Fails when compiled with Lua 5.0 types
const isClassicLua = _VERSION.includes("Lua 5.0") || _VERSION === "Lua 5.1";
const isClassicLua = _VERSION.includes("Lua 5.0");
if (isClassicLua || (caller && caller.func !== error)) {
return description;
} else {
Expand All @@ -55,7 +62,7 @@ export const Error: ErrorConstructor = initErrorClass(
public stack?: string;

constructor(public message = "") {
this.stack = getErrorStack((this.constructor as any).new);
this.stack = getErrorStack(__TS__New as any);
const metatable = getmetatable(this);
if (metatable && !metatable.__errorToStringPatched) {
metatable.__errorToStringPatched = true;
Expand Down
25 changes: 25 additions & 0 deletions test/unit/error.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as util from "../util";
import * as tstl from "../../src";

test("throwString", () => {
util.testFunction`
Expand Down Expand Up @@ -343,3 +344,27 @@ test("still works without debug module", () => {
stack: undefined,
});
});

util.testEachVersion(
"error stacktrace omits constructor and __TS_New",
() => util.testFunction`
const e = new Error();
return e.stack;
`,
{
...util.expectEachVersionExceptJit(builder => {
builder.expectToHaveNoDiagnostics();
const luaResult = builder.getLuaExecutionResult();
// eslint-disable-next-line jest/no-standalone-expect
expect(luaResult.split("\n")).toHaveLength(4);
}),

// 5.0 debug.traceback doesn't support levels
[tstl.LuaTarget.Lua50](builder) {
builder.expectToHaveNoDiagnostics();
const luaResult = builder.getLuaExecutionResult();
// eslint-disable-next-line jest/no-standalone-expect
expect(luaResult).toContain("Level 4");
},
}
);
4 changes: 2 additions & 2 deletions test/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; l
return { lauxlib, lua, lualib };
}
if (target === tstl.LuaTarget.LuaJIT) {
throw Error("Can't use executeLua() or expectToMatchJsResult() wit LuaJIT as target!");
throw Error("Can't use executeLua() or expectToMatchJsResult() with LuaJIT as target!");
}

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

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