Repository navigation
E2E quit check: time a quit from when it reaches main; check apps that quit on their own - #13
Merged
Merged
Conversation
…cks apps that quit on their own, and samples a stuck main thread on macOS Follow-ups F1, F2 and F4 from PR #11's review (D28). - F1: Playwright does work of its own before it asks Orbit to quit (5 s after a failed test, measured by the reviewer), and the 15 s clock used to include it. In e2e mode main now logs "[orbit] quit requested" in before-quit; Orbit gets 15 s from that line, or 35 s from app.close() if the line never comes. The failure says which. - F2: an app that quits on its own (its last window closed) had no app.close() to check it. It is now remembered when it closes, and the next launchOrbit() checks it. - F4: macOS has no /proc, so a kill said "main thread: unknown". It now runs `sample <pid> 1` and reports the main thread's deepest frames, with the full sample's path. Not run on macOS yet; any error still falls back to "unknown". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 8923aecd-68fc-43f9-9e28-34d743d9cc86) |
…thing handled in main Electron only prints a warning for an unhandled rejection in the main process, so the D28 check never saw one. Main now logs them with the same marker as an uncaught exception, so the check fails the test that caused it. The new TB-22 test fails without the logging (received "") and passes with it. PR #11 review F3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… rejection behind Waking a tab restores its history. If the tab closed before the restore finished, restore's catch loaded the page into contents already destroyed: loadURL threw "Object has been destroyed", and the rejection went unhandled (archive review F8, seen after archive's restore tests at quit). load() now does nothing for destroyed contents. The new TB-22 test fails without the fix, now that the quit check sees rejections (Received: "[orbit] uncaught exception: (a promise rejection nothing handled) TypeError: Object has been destroyed"), and passes 3/3 with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 1dbf0c3d-6134-43ea-aee4-3ac75069d9fb) |
One conflict, tests/e2e/helpers.ts: media's launchOrbit options (reducedMotion and args) with PR #13's check of an app that quit on its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 668c0111-db91-4488-8b1c-d28098d66aeb) |
siyabendoezdemir
added a commit
that referenced
this pull request
Oct 10, 2026
docs/ARCHITECTURE.md §9: main's E2E bullet (the quit clock now starts when the quit reaches main) with this branch's merge-gate bullet, which now also gives the gate's exact e2e command (lead-scope review F2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Was stacked on PR #11 (base
lead/quit). #11 has merged, so the base ismainnow. Four follow-ups from PR #11's review (reviews/lead-quit.md: F1, F2, F3 and F4), all about the e2e quit check (D28). Also the one bug F3 found inmain's code (archive review F8).What
F1: the 15 s clock starts when the quit reaches Orbit (
tests/e2e/helpers.ts,src/main/index.ts).app.close(). Playwright does work of its own before it asks Orbit to quit; after a failed test the reviewer measured 5.0 s of it. On a runner about 3× slower, a healthy quit after a failed test could be killed, and the report would blame the quit.[orbit] quit requestedinbefore-quit. Orbit gets 15 s from that line. If the line never comes, the kill happens 35 s afterapp.close().still running: it had the quit for 15 s (main thread: …)orstill running: the quit never reached its main process (…).F2: an app that quits on its own is checked too.
app.close()on that app, so an exception it threw while quitting went unnoticed.launchOrbit()checks it before starting another. A test that ends without relaunching still checks it through its ownapp.close()inafterEach.F4: on macOS, a kill shows the main thread's stack.
/procon macOS, so the kill reportedmain thread: unknown. The hangs that are still unexplained (CB-21, MW-14) happened there.sample <pid> 1and puts the main thread's deepest 40 frames in the failure, with the path of the full sample.unknown, as before.F3: a promise rejection nothing handled fails the test too (
src/main/index.ts).[orbit] uncaught exception: (a promise rejection nothing handled) …), in every mode, like the exception handler. The check fails the test that caused it.Received string: "") and passes with it.The rejection it found: a tab closed while its history restores (
src/main/tabs/runtime.ts, archive review F8).loadURLthrewObject has been destroyed, and nothing handled the rejection. The archive reviewer saw it after archive's restore tests.load()now does nothing for destroyed contents.TypeError: Object has been destroyed) and passes with it, 3 of 3.main's code (below). Lanes will meet it for their own code when they merge this.Checks
before-quitlistener added in front of Orbit's busy-waits 17 s, so the quit reaches Orbit's own handler late.lead/quit): killed at 15.1 s:still running (main thread: 0). Fails.app.close()took 17.2 s; not killed. Passes.will-quitlistener throws, then every window closes, so Orbit quits on its own; the test then relaunches.Orbit's main process threw an exception nothing caught … boom while quitting alone.core,spaces,tabs-more,smokeandsplit: 116/116 passed (4.6 min);commandbar: 36/36 (1.2 min);tabs: 15/15 (49 s).8223aa5(1440×900, 1 worker): 221/221 passed (9.2 min), exit 0. No exception was logged and no quit needed the kill.a151ced(1440×900, 1 worker): 222 passed, 1 failed (13.4 min). No test logged an uncaught exception or an unhandled rejection, and no quit needed the kill.commandbar.spec.ts:838: open took 73.5 ms against 50 ms). The load average was 41–49 on 16 cores; it passed alone right after.npm run build,npm run typecheck,npm run lint: exit 0. Unit tests: 255/255.Not in this PR
Merge with
main(PRs #10, #11 and #9), and the local check (merge gate, D42)GitHub Actions is off for cost, so a local check is the merge gate. PRs #10, #11 and #9 merged first. This branch is fast-forwarded to
87f488d, which merges this PR (a151ced) intoda6a207, whose tree ismain's now.mainadds nothing on top of it, so87f488d's tree is exactly what lands.tests/e2e/helpers.ts:launchOrbit()keepsmain'sreducedMotionandargsoptions, and checks an app that quit on its own (F2) before launching another.87f488d(Linux, 1440×900, 1 worker):test.fixmetests for players inside frames (MD-01, MD-09).samplepath has never run, and the macOS-only hangs (CB-21, MW-14) are still unexplained.Review
reviews/lead-harness.md(an independent reviewer, ata151cedplus87f488d's merge): approve, no must-fix. It checked that the check still catches everything PR #11's did, with scratch specs, and that each fix's test fails without it. Five follow-ups for later:before-quitlisteners, so a hang in one of them is reported as a quit that never reached main.app.close()can be killed before its 15 s are up, and the kill names the wrong cause.launchOrbit(), which may be the next test or none.samplecan't run here; the reviewer is moderately sure it works.await closedhas no time limit, as in PR Main-process exceptions no longer block quitting (D28): the check, the strip's fade timer, two test races #11.🤖 Generated with Claude Code
Note
Medium Risk
Changes main-process error handling and tab load paths during restore/teardown; e2e harness behavior only in tests but alters how quit failures are diagnosed in CI.
Overview
Tightens the e2e quit/health harness (D28) and fixes a tab-runtime bug that showed up under the stricter checks.
The 15 s stuck-quit timer now starts when main logs
[orbit] quit requestedinbefore-quit(e2e only), not when Playwright callsapp.close(). If quit never reaches main, the harness kills after 35 s and reports whether the process had the quit for 15 s or never saw it. Self-quitting apps (last window closed) are queued and verified on the nextlaunchOrbit()or their ownapp.close(). On macOS, a stuck kill includes a one-secondsampleof the main thread instead ofunknown.Main now logs unhandled promise rejections with the same
[orbit] uncaught exception:marker as sync throws, so e2e fails those tests too.TabRuntime.loadno-ops whenWebContentsis already destroyed, avoiding an unhandled rejection when a tab is closed mid–history restore.New TB-22 e2e cases cover rejection logging and mid-restore close;
docs/ARCHITECTURE.md§9 documents the updated quit rules.Reviewed by Cursor Bugbot for commit 87f488d. Bugbot is set up for automated code reviews on this repo. Configure here.