-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[Reporting] Handle error gracefully when browser driver unexpectedly exits or crashes. #71989
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4a7fc3c
ffbbafc
7bc1733
ad52460
0fc4c0a
11102dc
aaf35a7
50db01a
49f67b4
6e25ba5
1f3f127
f96e0d1
6e3f8ef
0bc8312
e33e4f9
a6f798c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ import { | |
| import * as Rx from 'rxjs'; | ||
| import { InnerSubscriber } from 'rxjs/internal/InnerSubscriber'; | ||
| import { ignoreElements, map, mergeMap, tap } from 'rxjs/operators'; | ||
| import { getChromiumDisconnectedError } from '../'; | ||
| import { BROWSER_TYPE } from '../../../../common/constants'; | ||
| import { CaptureConfig } from '../../../../server/types'; | ||
| import { LevelLogger } from '../../../lib'; | ||
|
|
@@ -115,13 +116,19 @@ export class HeadlessChromiumDriverFactory { | |
|
|
||
| logger.debug(`Browser page driver created`); | ||
| } catch (err) { | ||
| observer.error(new Error(`Error spawning Chromium browser: [${err}]`)); | ||
| observer.error(new Error(`Error spawning Chromium browser!`)); | ||
| observer.error(err); | ||
|
||
| throw err; | ||
| } | ||
|
|
||
| const childProcess = { | ||
| async kill() { | ||
| await browser.close(); | ||
| try { | ||
| await browser.close(); | ||
| } catch (err) { | ||
| // do not throw | ||
| logger.error(err); | ||
| } | ||
| }, | ||
| }; | ||
| const { terminate$ } = safeChildProcess(logger, childProcess); | ||
|
|
@@ -167,7 +174,8 @@ export class HeadlessChromiumDriverFactory { | |
| // the unsubscribe function isn't `async` so we're going to make our best effort at | ||
| // deleting the userDataDir and if it fails log an error. | ||
| del(userDataDir, { force: true }).catch((error) => { | ||
| logger.error(`error deleting user data directory at [${userDataDir}]: [${error}]`); | ||
| logger.error(`error deleting user data directory at [${userDataDir}]!`); | ||
| logger.error(error); | ||
| }); | ||
| }); | ||
| }); | ||
|
|
@@ -219,7 +227,7 @@ export class HeadlessChromiumDriverFactory { | |
| mergeMap((err) => { | ||
| return Rx.throwError( | ||
| i18n.translate('xpack.reporting.browsers.chromium.errorDetected', { | ||
| defaultMessage: 'Reporting detected an error: {err}', | ||
| defaultMessage: 'Reporting encountered an error: {err}', | ||
| values: { err: err.toString() }, | ||
| }) | ||
| ); | ||
|
|
@@ -230,23 +238,15 @@ export class HeadlessChromiumDriverFactory { | |
| mergeMap((err) => { | ||
| return Rx.throwError( | ||
| i18n.translate('xpack.reporting.browsers.chromium.pageErrorDetected', { | ||
| defaultMessage: `Reporting detected an error on the page: {err}`, | ||
| defaultMessage: `Reporting encountered an error on the page: {err}`, | ||
| values: { err: err.toString() }, | ||
| }) | ||
| ); | ||
| }) | ||
| ); | ||
|
|
||
| const browserDisconnect$ = Rx.fromEvent(browser, 'disconnected').pipe( | ||
| mergeMap(() => | ||
| Rx.throwError( | ||
| new Error( | ||
| i18n.translate('xpack.reporting.browsers.chromium.chromiumClosed', { | ||
| defaultMessage: `Reporting detected that Chromium has closed.`, | ||
| }) | ||
| ) | ||
| ) | ||
| ) | ||
| mergeMap(() => Rx.throwError(getChromiumDisconnectedError())) | ||
| ); | ||
|
|
||
| return Rx.merge(pageError$, uncaughtExceptionPageError$, browserDisconnect$); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import { i18n } from '@kbn/i18n'; | ||
| import { BrowserDownload } from '../'; | ||
| import { CaptureConfig } from '../../../server/types'; | ||
| import { LevelLogger } from '../../lib'; | ||
|
|
@@ -15,3 +16,18 @@ export const chromium: BrowserDownload = { | |
| createDriverFactory: (binaryPath: string, captureConfig: CaptureConfig, logger: LevelLogger) => | ||
| new HeadlessChromiumDriverFactory(binaryPath, captureConfig, logger), | ||
| }; | ||
|
|
||
| export const getChromiumDisconnectedError = () => | ||
|
||
| new Error( | ||
| i18n.translate('xpack.reporting.screencapture.browserWasClosed', { | ||
| defaultMessage: 'Browser was closed unexpectedly! Check the server logs for more info.', | ||
| }) | ||
| ); | ||
|
|
||
| export const getDisallowedOutgoingUrlError = (interceptedUrl: string) => | ||
| new Error( | ||
| i18n.translate('xpack.reporting.chromiumDriver.disallowedOutgoingUrl', { | ||
| defaultMessage: `Received disallowed outgoing URL: "{interceptedUrl}". Failing the request and closing the browser.`, | ||
| values: { interceptedUrl }, | ||
| }) | ||
| ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import { HeadlessChromiumDriver } from '../../browsers'; | ||
| import { getChromiumDisconnectedError } from '../../browsers/chromium'; | ||
|
|
||
| /* | ||
| * Call this function within error-handling `catch` blocks while setup and wait | ||
| * for the Kibana URL to be ready for screenshot. This detects if a block of | ||
| * code threw an exception because the page is closed or crashed. | ||
| * | ||
| * Also call once after `setup$` fires in the screenshot pipeline | ||
| */ | ||
| export const checkPageIsOpen = (browser: HeadlessChromiumDriver) => { | ||
| if (!browser.isPageOpen()) { | ||
| throw getChromiumDisconnectedError(); | ||
| } | ||
| }; |
Uh oh!
There was an error while loading. Please reload this page.