Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promise tests down #1105

Closed
websharik opened this issue Aug 26, 2021 · 1 comment · Fixed by #1150
Closed

Promise tests down #1105

websharik opened this issue Aug 26, 2021 · 1 comment · Fixed by #1150
Labels
bug scope: lualib Lualib, polyfills

Comments

@websharik
Copy link

websharik commented Aug 26, 2021

tsconfig:

{
    "compilerOptions": {
        "target": "ESNext",
        "lib": ["ESNext"],
        "module": "commonjs",
        "strict": true,
        "baseUrl": ".",
        "rootDir": "src",
        "outDir": "dist",
        "paths": {},
        "plugins": [
            {
                "transform": "mtasa-lua-utils/transformer",
                "after": false,
                "externalImports": true,
                "globalExports": false
            }
        ],
        "types": ["lua-types/5.1"],
        "forceConsistentCasingInFileNames": true,
        "noImplicitAny": true,
        "noImplicitThis": true,
        "strictNullChecks": true,
        "strictFunctionTypes": true
    },
    "tstl": {
        "luaTarget": "5.1",
        "noImplicitSelf": true,
        "luaLibImport": "none",
        "sourceMapTraceback": false,
        "noHeader": true
    },
    "bundleEntryPoints": ["src/test.ts"]
}
  1. Just await not working
(async () => {
    print('Start')
    try {
        let text = await new Promise((resolve) => { resolve("Success text") })
        print(text)
    } catch (e) {
        print(`Somethings wrong global: ${e}`)
    }
    print('End')
})()

Result:

Start
Somethings wrong global: test\vendor\lualib_bundle.lua:538: attempt to yield across metamethod/C-call boundary
End
function __TS__Await(thing)
    return coroutine.yield(thing)
end

Expected:

Start
Success text
End

But then is working:

(async () => {
    print('Start')
    try {
        new Promise((resolve) => { resolve("Success text") })
        .then((text) => {
            print(text)
        })
    } catch (e) {
        print(`Somethings wrong global: ${e}`)
    }
    print('End')
})()

Result:

Start
Success text
End
  1. Catch after then not working
(async () => {
    print('Start')
    try {
        Promise.reject('Error text')
        .then((result) => {
            print(`Result: ${result}`)
        })
        .catch((e) => {
            print(`Somethings wrong local: ${e}`)
        })
    } catch (e) {
        print(`Somethings wrong global: ${e}`)
    }
    print('End')
})()

Result:

Start
End

Expected:

Start
Somethings wrong local: Error text
End

But without .then, .catch working:

(async () => {
    print('Start')
    try {
        Promise.reject('Error text')
        .catch((e) => {
            print(`Somethings wrong local: ${e}`)
        })
    } catch (e) {
        print(`Somethings wrong global: ${e}`)
    }
    print('End')
})()

Result:

Start
Somethings wrong local: Error text
End
  1. Global catch not working
(async () => {
    print('Start')
    try {
        await new Promise((resolve, reject) => {
            reject('Error text')
        })
    } catch (e) {
        print(`Somethings wrong global: ${e}`)
    }
    print('End')
})()

Result:

Start
End

Expected:

Start
Somethings wrong global: Error text
End
@Perryvw
Copy link
Member

Perryvw commented Sep 4, 2021

This seems due to a specific interaction between pcall (used for try/catch) and coroutines (used for async), exclusive to Lua 5.1. Move information can be found here: http://lua-users.org/wiki/PcallAndCoroutines

I'm not entirely sure how to fix this yet, possibly we could decide to translate try/catch to a coroutine-safe implementation of pcall, as done here: https://github.com/keplerproject/coxpcall This would incur some performance penalty, but I doubt it is a big problem, the number of try/catch statements will probably be limited.

I considered the fact we could only do this special case if we are in an async function, but that seems impractical since the problem would also occur when using try/catch in a synchronous function that is called in an async function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug scope: lualib Lualib, polyfills
Projects
None yet
2 participants