fix: Handle missing xdg-open (ENOENT) gracefully to prevent crash#1675
fix: Handle missing xdg-open (ENOENT) gracefully to prevent crash#1675Ojhaharsh wants to merge 7 commits intoQwenLM:mainfrom
Conversation
|
Hi @DennisYu07 / team! |
wenshao
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅ — gpt-5.4 via Qwen Code /review
|
Thanks for the PR, but I don't think this lands the fix in the right place, and it introduces a behavior regression on the path it does change. A few concerns: 1. This likely doesn't address #1674. The stack trace in the issue shows an The initialization path that actually launches a browser on first run is 2. Behavior regression for the one real caller.
If logging-and-continuing is the right behavior, it should be the caller's choice, not baked into the utility. 3. The new test is platform-dependent and will likely fail on Linux CI. The test doesn't call Suggestion: Split this into two PRs.
|
|
Thanks for the thorough review! |
wenshao
left a comment
There was a problem hiding this comment.
[Suggestion] packages/core/src/utils/secure-browser-launcher.ts:49 still documents browser-launch failure as throwing, but the new implementation now logs the URL and resolves instead. Please update the JSDoc so the exported contract matches the new behavior.
— gpt-5.4 via Qwen Code /review
| ); | ||
| }); | ||
| }); | ||
|
|
There was a problem hiding this comment.
[Critical] This test is platform-dependent because it never fixes the platform before asserting the logging path. On Linux, openBrowserSecurely() retries fallback browsers after xdg-open fails, and the default mock makes the next launch succeed, so console.error is never reached and this assertion will fail on Linux CI.
| it('should handle browser launch failures gracefully by logging instead of throwing', async () => { | |
| setPlatform('darwin'); | |
| // Simulate a failure (like missing xdg-open) | |
| mockExecFile.mockRejectedValueOnce(new Error('Command failed')); | |
| // Spy on the console to make sure we log the message | |
| const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); | |
| // THE FIX: We expect this to RESOLVE (succeed), not REJECT (crash) | |
| await expect( | |
| openBrowserSecurely('https://example.com'), | |
| ).resolves.toBeUndefined(); | |
| // Verify we logged the helpful message | |
| expect(consoleSpy).toHaveBeenCalledWith( | |
| expect.stringContaining('Failed to open browser automatically'), | |
| ); | |
| consoleSpy.mockRestore(); | |
| }); |
— gpt-5.4 via Qwen Code /review
test: fix platform dependency by setting darwin and asserting resolve
|
Hi @wenshao , Thanks for the detailed feedback! I've addressed the two specific requested changes:
Regarding your earlier suggestion to split this into two PRs:
Let me know if this approach works for you! |
wenshao
left a comment
There was a problem hiding this comment.
No issues found. LGTM! ✅ — gpt-5.4 via Qwen Code /review
Dismissing — CI Lint job is failing (build error). Re-approving once green.
|
Hi @Ojhaharsh — just dismissed my approval because CI is red on this commit. The Lint job fails with a TypeScript build error: The import path is relative to Failing job: https://github.com/QwenLM/qwen-code/actions/runs/24640120703/job/72042482230 Could you fix and push? Happy to re-approve once CI is green. Thanks! |
|
Hi @wenshao, Thanks for your patience! I've addressed the specific requested changes:
Regarding CI FailuresThe Lint check is now ✅ green. However, several unrelated integration tests ( Next Steps (Splitting PRs)As you suggested, I am treating this PR as the "Utility Stabilization" piece (docs + tests + lint). Once this is merged, I will immediately open a second separate PR to fix the actual root cause crash in Could you please review these changes? If the unrelated test failures are blocking, let me know, but I believe they are environmental. Thanks! |
|
Walking back through the open items after dismissing today's Confirmed addressed ✅
Blocking — Lint is redThe new import Still unaddressed from my 2026-04-18 reviewYou replied on 2026-04-19 09:03: "I'll split this into two PRs as suggested." — but this PR still bundles:
and the real source of #1674 — Suggested split still stands:
If you want to keep it as one PR, please push back on concern #2 from my 2026-04-18 comment specifically: SummaryJSDoc + platform-pin test are landed. Open: fix the import so Lint goes green, and settle the split question. Happy to re-review once both are resolved. |
|
Hi @wenshao, Update: The Lint check is now green ✅! The Regarding the 9 failing tests: These appear to be the same pre-existing flaky integration tests ( Next Steps (Splitting PRs):
I'll close this PR once the new ones are open. Thanks! |
|
Hi @wenshao, As requested, I have successfully split the work into two PRs:
Both are ready for your review :) |
| ).resolves.toBeUndefined(); | ||
|
|
||
| // Verify we logged the helpful message | ||
| expect(consoleSpy).toHaveBeenCalledWith( |
There was a problem hiding this comment.
[Critical] This new test spies on console.error, but the implementation now logs via console.warn, so the package-local test fails deterministically. Please make the assertion match the implementation (or switch the implementation back and keep docs/tests aligned).
| expect(consoleSpy).toHaveBeenCalledWith( | |
| // Spy on console.warn to verify we log the message | |
| const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); |
— gpt-5.4 via Qwen Code /review
|
Hi @wenshao, I've resolved the merge conflict and updated ✅ Changed spy from The lint and tests for this utility fix should now be stable. As requested, the root cause crash fix has been moved to PR #3481, which is also passing all checks. Both PRs are ready for your final review! |
Problem
On headless environments or specific Linux distros (like RISC-V/OrangePi) where
xdg-openis missing or fails, the extension crashes with anUnhandled 'error' event. This addresses issue #1674.Solution
Updated
secure-browser-launcher.tsto catch the error when the browser command fails. Instead of throwing (and crashing the extension), it now logs the URL to the console so the user can open it manually.Verification