GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix break and continue inside try/catch in loops by bardrop · Pull Request #1741 · TypeScriptToLua/TypeScriptToLua

Conversation

@bardrop

@bardrop bardrop commented Nov 12, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Fixes #1598

A sync try or catch block is compiled to a Lua function (pcall(function() ... end) / local function ____catch() ... end). A break or continue inside it was emitted as a plain break / goto inside that function, so Lua refused to load the file:

for (const f of factionKeys) {
    try {
        GetFaction(f);
    } catch {
        break;
    }
}
local function ____catch()
    break -- error: break outside a loop
end

Async functions already handle this with flags (#1707). This uses the same approach for sync try/catch: break / continue set ____hasBroken / ____hasContinued and return, and the try statement checks the flag at its end (after finally and the rethrow check), then does the real break or continue:

do
    local ____hasBroken
    local function ____catch()
        ____hasBroken = true
        return
    end
    local ____try = pcall(function()
        GetFaction(f)
    end)
    if not ____try then
        ____catch()
    end
    if ____hasBroken then
        break
    end
end

break/continue and the post-try checks now share one helper (createBreak / createContinue in break-continue.ts), for both sync and async try. That also fixes two cases the async code got wrong:

  • break inside a switch inside a try broke out of the loop, not the switch. The search for an enclosing try now stops at the switch for break.
  • Nested try statements: the inner try's check emitted a plain break inside the outer try's function. Now only the outermost try inside the loop declares the flag; inner ones share it and return out of the outer try function.

Tests:

  • test/unit/error.spec.ts: break/continue from try, catch (with and without the error variable), try/finally, try/catch/finally, nested try, and a mix with return, in for, for...of, while and do...while. Run on universal, 5.0, 5.1 and 5.4, plus Luau for the break-only ones (the test VM can't run Luau's continue). Also checks that a break inside a switch or an inner loop inside a try only leaves that switch or loop.
  • test/unit/builtins/async-await.spec.ts: switch inside try, and nested try, in an async loop.

47 of the new tests fail before the change. The 6 that already pass are the switch / inner-loop guards in error.spec.ts and the 5.0/5.1 async runs, which only check the existing diagnostic. All pass after. Full jest run passes (6316 tests), and npm run lint passes.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bardrop
fix break and continue inside try/catch in loops (TypeScriptToLua#1598)
4a96a58
A sync try or catch block is compiled to a Lua function, so a break or
continue inside it was emitted as a Lua break/goto inside a function,
which is a syntax error. Now break and continue inside try/catch set a
flag and return, and the try statement breaks or continues after it
ran (after finally), as was already done for async functions.

Also for async and sync try:
- break inside a switch inside a try only leaves the switch
- nested try statements share one flag and return out of the outer try
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

loop with try catch body emitted invalid lua code

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@bardrop
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.