diff --git a/src/server/browserType.ts b/src/server/browserType.ts index 29443d556ac23..9929120c65a1a 100644 --- a/src/server/browserType.ts +++ b/src/server/browserType.ts @@ -90,7 +90,7 @@ export abstract class BrowserTypeBase implements BrowserType { assert(!(options as any).port, 'Cannot specify a port without launching as a server.'); options = validateLaunchOptions(options); const loggers = new Loggers(options.logger); - const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, loggers, undefined), loggers.browser, TimeoutSettings.timeout(options), `browserType.launch`); + const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, loggers, undefined), loggers.browser, TimeoutSettings.timeout(options), `browserType.launch`).catch(e => { throw this._rewriteStartupError(e); }); return browser; } @@ -99,7 +99,7 @@ export abstract class BrowserTypeBase implements BrowserType { options = validateLaunchOptions(options); const persistent = validateBrowserContextOptions(options); const loggers = new Loggers(options.logger); - const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, loggers, persistent, userDataDir), loggers.browser, TimeoutSettings.timeout(options), 'browserType.launchPersistentContext'); + const browser = await runAbortableTask(progress => this._innerLaunch(progress, options, loggers, persistent, userDataDir), loggers.browser, TimeoutSettings.timeout(options), 'browserType.launchPersistentContext').catch(e => { throw this._rewriteStartupError(e); }); return browser._defaultContext!; } @@ -240,6 +240,7 @@ export abstract class BrowserTypeBase implements BrowserType { abstract _startWebSocketServer(transport: ConnectionTransport, logger: Logger, port: number): WebSocketServer; abstract _amendEnvironment(env: Env, userDataDir: string, executable: string, browserArguments: string[]): Env; abstract _amendArguments(browserArguments: string[]): string[]; + abstract _rewriteStartupError(error: Error): Error; abstract _attemptToGracefullyCloseBrowser(transport: ConnectionTransport): void; } diff --git a/src/server/chromium.ts b/src/server/chromium.ts index 2f0a66eac58c9..f9dde856fd79a 100644 --- a/src/server/chromium.ts +++ b/src/server/chromium.ts @@ -22,6 +22,7 @@ import { CRBrowser } from '../chromium/crBrowser'; import * as ws from 'ws'; import { Env } from './processLauncher'; import { kBrowserCloseMessageId } from '../chromium/crConnection'; +import { rewriteErrorMessage } from '../utils/stackTrace'; import { BrowserTypeBase } from './browserType'; import { ConnectionTransport, ProtocolRequest, ProtocolResponse } from '../transport'; import { Logger } from '../logger'; @@ -63,6 +64,22 @@ export class Chromium extends BrowserTypeBase { return CRBrowser.connect(transport, options, devtools); } + _rewriteStartupError(error: Error): Error { + // These error messages are taken from Chromium source code as of July, 2020: + // https://github.com/chromium/chromium/blob/70565f67e79f79e17663ad1337dc6e63ee207ce9/content/browser/zygote_host/zygote_host_impl_linux.cc + if (!error.message.includes('crbug.com/357670') && !error.message.includes('No usable sandbox!') && !error.message.includes('crbug.com/638180')) + return error; + return rewriteErrorMessage(error, [ + `Chromium sandboxing failed!`, + `================================`, + `To workaround sandboxing issues, do either of the following:`, + ` - (preferred): Configure environment to support sandboxing: https://github.com/microsoft/playwright/blob/master/docs/troubleshooting.md`, + ` - (alternative): Launch Chromium without sandbox using 'chromiumSandbox: false' option`, + `================================`, + ``, + ].join('\n')); + } + _amendEnvironment(env: Env, userDataDir: string, executable: string, browserArguments: string[]): Env { return env; } @@ -71,6 +88,7 @@ export class Chromium extends BrowserTypeBase { // We currently only support Linux. if (os.platform() !== 'linux') return browserArguments; + // If there's already --no-sandbox passed in, do nothing. if (browserArguments.indexOf('--no-sandbox') !== -1) return browserArguments; diff --git a/src/server/firefox.ts b/src/server/firefox.ts index a57ef3106ceac..17de3552419b7 100644 --- a/src/server/firefox.ts +++ b/src/server/firefox.ts @@ -39,6 +39,10 @@ export class Firefox extends BrowserTypeBase { return FFBrowser.connect(transport, options); } + _rewriteStartupError(error: Error): Error { + return error; + } + _amendEnvironment(env: Env, userDataDir: string, executable: string, browserArguments: string[]): Env { return os.platform() === 'linux' ? { ...env, diff --git a/src/server/webkit.ts b/src/server/webkit.ts index c537517f0ed47..abf7df800ec9c 100644 --- a/src/server/webkit.ts +++ b/src/server/webkit.ts @@ -46,6 +46,10 @@ export class WebKit extends BrowserTypeBase { return browserArguments; } + _rewriteStartupError(error: Error): Error { + return error; + } + _attemptToGracefullyCloseBrowser(transport: ConnectionTransport): void { transport.send({method: 'Playwright.close', params: {}, id: kBrowserCloseMessageId}); }