mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 17:27:09 +00:00
fix(cli): a browser a sandbox refuses says to rerun the command with escalation (#5734)
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
import { normalizeErrorMessage } from "../utils/errorMessage.js";
|
||||
import { requestCliExit } from "../utils/commandResult.js";
|
||||
import { processIsAlive } from "../utils/processTree.js";
|
||||
import { sandboxDeniedRemediation } from "./sandboxDenied.js";
|
||||
|
||||
export class BrowserCleanupError extends AggregateError {}
|
||||
|
||||
@@ -94,6 +95,9 @@ export async function launchManagedBrowser(
|
||||
browsers.add(browser);
|
||||
child.once("exit", () => browsers.delete(browser));
|
||||
return browser;
|
||||
} catch (error) {
|
||||
const remediation = sandboxDeniedRemediation(normalizeErrorMessage(error));
|
||||
throw remediation ? new Error(remediation, { cause: error }) : error;
|
||||
} finally {
|
||||
pending.delete(launch);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { LaunchOptions, PuppeteerNode } from "puppeteer-core";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { launchManagedBrowser } from "./launch.js";
|
||||
|
||||
const SEATBELT_LAUNCH_FAILURE = [
|
||||
"Failed to launch the browser process: Code: null",
|
||||
"",
|
||||
"stderr:",
|
||||
"[1016/170315.389548:FATAL:base/apple/mach_port_rendezvous_mac.cc:159] Check failed: kr == KERN_SUCCESS. bootstrap_check_in org.chromium.Chromium.MachPortRendezvousServer.26166: Permission denied (1100)",
|
||||
].join("\n");
|
||||
|
||||
const failingPuppeteer = (message: string) =>
|
||||
({ launch: async (_: LaunchOptions) => Promise.reject(new Error(message)) }) as PuppeteerNode;
|
||||
|
||||
describe("a browser launch a sandbox refuses", () => {
|
||||
it("tells the caller to rerun with escalation instead of showing Chrome's crash", async () => {
|
||||
await expect(
|
||||
launchManagedBrowser(failingPuppeteer(SEATBELT_LAUNCH_FAILURE), {}),
|
||||
).rejects.toMatchObject({
|
||||
message:
|
||||
"The browser can't start inside this sandbox: macOS refused Chrome's mach service (bootstrap_check_in: Permission denied).\nRerun this command with escalation, outside the sandbox.",
|
||||
cause: { message: SEATBELT_LAUNCH_FAILURE },
|
||||
});
|
||||
});
|
||||
|
||||
it("leaves any other launch failure as it was", async () => {
|
||||
const other = "Failed to launch the browser process: Code: 1";
|
||||
await expect(launchManagedBrowser(failingPuppeteer(other), {})).rejects.toThrow(other);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
const MACH_SERVICE_DENIED = /bootstrap_check_in\b[^\n]*Permission denied/;
|
||||
|
||||
/** A process sandbox (an agent's macOS seatbelt) refused Chrome its mach service, so no browser starts here. */
|
||||
export function sandboxDeniedRemediation(errorMessage: string): string | undefined {
|
||||
if (!MACH_SERVICE_DENIED.test(errorMessage)) return undefined;
|
||||
return [
|
||||
"The browser can't start inside this sandbox: macOS refused Chrome's mach service (bootstrap_check_in: Permission denied).",
|
||||
"Rerun this command with escalation, outside the sandbox.",
|
||||
].join("\n");
|
||||
}
|
||||
@@ -118,6 +118,7 @@ import {
|
||||
import { chromeLaunchRemediation } from "../browser/linuxDeps.js";
|
||||
import { macosOldChromeCrashRemediation } from "../browser/macosOldChromeCrash.js";
|
||||
import { windowsChromeCrashRemediation } from "../browser/windowsCrash.js";
|
||||
import { sandboxDeniedRemediation } from "../browser/sandboxDenied.js";
|
||||
import { killOrphanedProcessesForRender } from "../utils/orphanCleanup.js";
|
||||
import { createRenderCancellationScope } from "../utils/renderCancellation.js";
|
||||
import {
|
||||
@@ -1759,6 +1760,11 @@ function handleRenderError(
|
||||
// failure on Linux/WSL is an environment problem, not a composition bug.
|
||||
// Replace the generic "Try --docker" hint with the exact per-distro
|
||||
// remediation and a pointer at `doctor`.
|
||||
const sandboxRemediation = sandboxDeniedRemediation(message);
|
||||
if (sandboxRemediation) {
|
||||
errorBox("Render failed — Chrome could not launch", message, sandboxRemediation);
|
||||
failCommand();
|
||||
}
|
||||
const remediation = chromeLaunchRemediation(message);
|
||||
if (remediation) {
|
||||
errorBox("Render failed — Chrome could not launch", message, remediation);
|
||||
|
||||
Reference in New Issue
Block a user