cli: write report in runLighthouse before quitting Chrome (#7339)

This commit is contained in:
Brendan Kenny 2019-03-01 15:15:35 -08:00 коммит произвёл GitHub
Родитель 01b09d078e
Коммит a1f0b6245f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 60 добавлений и 59 удалений

Просмотреть файл

@ -62,53 +62,57 @@ function getDebuggableChrome(flags) {
});
}
/** @return {never} */
function showConnectionError() {
console.error('Unable to connect to Chrome');
process.exit(_RUNTIME_ERROR_CODE);
return process.exit(_RUNTIME_ERROR_CODE);
}
/** @return {never} */
function showProtocolTimeoutError() {
console.error('Debugger protocol timed out while connecting to Chrome.');
process.exit(_PROTOCOL_TIMEOUT_EXIT_CODE);
return process.exit(_PROTOCOL_TIMEOUT_EXIT_CODE);
}
/** @param {LH.LighthouseError} err */
/** @param {LH.LighthouseError} err @return {never} */
function showPageHungError(err) {
console.error('Page hung:', err.friendlyMessage);
process.exit(_PAGE_HUNG_EXIT_CODE);
return process.exit(_PAGE_HUNG_EXIT_CODE);
}
/** @param {LH.LighthouseError} err */
/** @param {LH.LighthouseError} err @return {never} */
function showInsecureDocumentRequestError(err) {
console.error('Insecure document request:', err.friendlyMessage);
process.exit(_INSECURE_DOCUMENT_REQUEST_EXIT_CODE);
return process.exit(_INSECURE_DOCUMENT_REQUEST_EXIT_CODE);
}
/**
* @param {LH.LighthouseError} err
* @return {never}
*/
function showRuntimeError(err) {
console.error('Runtime error encountered:', err.friendlyMessage || err.message);
if (err.stack) {
console.error(err.stack);
}
process.exit(_RUNTIME_ERROR_CODE);
return process.exit(_RUNTIME_ERROR_CODE);
}
/**
* @param {LH.LighthouseError} err
* @return {never}
*/
function handleError(err) {
if (err.code === 'ECONNREFUSED') {
showConnectionError();
return showConnectionError();
} else if (err.code === 'CRI_TIMEOUT') {
showProtocolTimeoutError();
return showProtocolTimeoutError();
} else if (err.code === 'PAGE_HUNG') {
showPageHungError(err);
return showPageHungError(err);
} else if (err.code === 'INSECURE_DOCUMENT_REQUEST') {
showInsecureDocumentRequestError(err);
return showInsecureDocumentRequestError(err);
} else {
showRuntimeError(err);
return showRuntimeError(err);
}
}
@ -159,66 +163,63 @@ async function saveResults(runnerResult, flags) {
}
}
/**
* Attempt to kill the launched Chrome, if defined.
* @param {ChromeLauncher.LaunchedChrome=} launchedChrome
* @return {Promise<void>}
*/
async function potentiallyKillChrome(launchedChrome) {
if (!launchedChrome) return;
return Promise.race([
launchedChrome.kill(),
new Promise((_, reject) => setTimeout(reject, 5000, 'Timed out.')),
]).catch(err => {
throw new Error(`Couldn't quit Chrome process. ${err}`);
});
}
/**
* @param {string} url
* @param {LH.CliFlags} flags
* @param {LH.Config.Json|undefined} config
* @return {Promise<LH.RunnerResult|void>}
* @return {Promise<LH.RunnerResult|undefined>}
*/
function runLighthouse(url, flags, config) {
/** @type {ChromeLauncher.LaunchedChrome|undefined} */
let launchedChrome;
const shouldGather = flags.gatherMode || flags.gatherMode === flags.auditMode;
let chromeP = Promise.resolve();
process.on('unhandledRejection', async (reason) => {
async function runLighthouse(url, flags, config) {
/** @param {any} reason */
async function handleTheUnhandled(reason) {
process.stderr.write(`Unhandled Rejection. Reason: ${reason}\n`);
try {
await potentiallyKillChrome();
} catch (err) {
process.stderr.write(`Couldn't quit Chrome process. ${err.toString()}\n`);
}
await potentiallyKillChrome(launchedChrome).catch(() => {});
setTimeout(_ => {
process.exit(1);
}, 100);
});
if (shouldGather) {
chromeP = chromeP.then(_ =>
getDebuggableChrome(flags).then(launchedChromeInstance => {
launchedChrome = launchedChromeInstance;
flags.port = launchedChrome.port;
})
);
}
process.on('unhandledRejection', handleTheUnhandled);
const resultsP = chromeP.then(_ => {
return lighthouse(url, flags, config).then(runnerResult => {
return potentiallyKillChrome().then(_ => runnerResult);
}).then(async runnerResult => {
// If in gatherMode only, there will be no runnerResult.
if (runnerResult) {
await saveResults(runnerResult, flags);
}
/** @type {ChromeLauncher.LaunchedChrome|undefined} */
let launchedChrome;
return runnerResult;
});
});
return resultsP.catch(err => {
return Promise.resolve()
.then(_ => potentiallyKillChrome())
.then(_ => handleError(err));
});
/**
* @return {Promise<{}>}
*/
function potentiallyKillChrome() {
if (launchedChrome !== undefined) {
return launchedChrome.kill();
try {
const shouldGather = flags.gatherMode || flags.gatherMode === flags.auditMode;
if (shouldGather) {
launchedChrome = await getDebuggableChrome(flags);
flags.port = launchedChrome.port;
}
return Promise.resolve({});
const runnerResult = await lighthouse(url, flags, config);
// If in gatherMode only, there will be no runnerResult.
if (runnerResult) {
await saveResults(runnerResult, flags);
}
await potentiallyKillChrome(launchedChrome);
process.removeListener('unhandledRejection', handleTheUnhandled);
return runnerResult;
} catch (err) {
await potentiallyKillChrome(launchedChrome).catch(() => {});
handleError(err);
}
}