Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
async computeOptimizedImages(driver, imageRecords) {
this._encodingStartAt = Date.now();
/** @type {LH.Artifacts['OptimizedImages']} */
const results = [];
for (const record of imageRecords) {
try {
const stats = await this.calculateImageStats(driver, record);
/** @type {LH.Artifacts.OptimizedImage} */
const image = {failed: false, ...stats, ...record};
results.push(image);
} catch (err) {
log.warn('optimized-images', err.message);
// Track this with Sentry since these errors aren't surfaced anywhere else, but we don't
// want to tank the entire run due to a single image.
Sentry.captureException(err, {
tags: {gatherer: 'OptimizedImages'},
extra: {imageUrl: URL.elideDataURI(record.url)},
level: 'warning',
});
/** @type {LH.Artifacts.OptimizedImageError} */
const imageError = {failed: true, errMsg: err.message, ...record};
results.push(imageError);
}
}
return results;
'service_workers',
'cache_storage',
].join(',');
// `Storage.clearDataForOrigin` is one of our PROTOCOL_TIMEOUT culprits and this command is also
// run in the context of PAGE_HUNG to cleanup. We'll keep the timeout low and just warn if it fails.
this.setNextProtocolTimeout(5000);
try {
await this.sendCommand('Storage.clearDataForOrigin', {
origin: origin,
storageTypes: typesToClear,
});
} catch (err) {
if (/** @type {LH.LighthouseError} */(err).code === 'PROTOCOL_TIMEOUT') {
log.warn('Driver', 'clearDataForOrigin timed out');
} else {
throw err;
}
}
}
id: `lh:audit:${audit.meta.id}`,
};
log.time(status);
let auditResult;
try {
// Return an early error if an artifact required for the audit is missing or an error.
for (const artifactName of audit.meta.requiredArtifacts) {
const noArtifact = artifacts[artifactName] === undefined;
// If trace required, check that DEFAULT_PASS trace exists.
// TODO: need pass-specific check of networkRecords and traces.
const noTrace = artifactName === 'traces' && !artifacts.traces[Audit.DEFAULT_PASS];
if (noArtifact || noTrace) {
log.warn('Runner',
`${artifactName} gatherer, required by audit ${audit.meta.id}, did not run.`);
throw new Error(`Required ${artifactName} gatherer did not run.`);
}
// If artifact was an error, output error result on behalf of audit.
if (artifacts[artifactName] instanceof Error) {
/** @type {Error} */
// @ts-ignore An artifact *could* be an Error, but caught here, so ignore elsewhere.
const artifactError = artifacts[artifactName];
Sentry.captureException(artifactError, {
tags: {gatherer: artifactName},
level: 'error',
});
log.warn('Runner', `${artifactName} gatherer, required by audit ${audit.meta.id},` +
delete this.chrome;
this.destroyTmp().then(resolve);
});
log.log('ChromeLauncher', `Killing Chrome instance ${this.chrome.pid}`);
try {
if (isWindows) {
// While pipe is the default, stderr also gets printed to process.stderr
// if you don't explicitly set `stdio`
execSync(`taskkill /pid ${this.chrome.pid} /T /F`, {stdio: 'pipe'});
} else {
process.kill(-this.chrome.pid);
}
} catch (err) {
const message = `Chrome could not be killed ${err.message}`;
log.warn('ChromeLauncher', message);
reject(new Error(message));
}
} else {
// fail silently as we did not start chrome
resolve();
}
});
}
static filterAccordingToOptions(items, options) {
const {ignoredPatterns, ...restOfOptions} = options;
const otherOptionKeys = Object.keys(restOfOptions);
if (otherOptionKeys.length) log.warn(this.meta.id, 'Unrecognized options', otherOptionKeys);
if (!ignoredPatterns) return items;
return items.filter(({description}) => {
if (!description) return true;
for (const pattern of ignoredPatterns) {
if (pattern instanceof RegExp && pattern.test(description)) return false;
if (typeof pattern === 'string' && description.includes(pattern)) return false;
}
return true;
});
}
}).then(content => {
const styleHeader = this._activeStyleHeaders[sheetId];
styleHeader.content = content.text;
const parsedContent = parser.parse(styleHeader.content);
if (parsedContent.error) {
const error = parsedContent.error.toString().slice(0, 100);
log.warn('Styles Gatherer', `Could not parse content: ${error}…`);
styleHeader.parsedContent = [];
} else {
styleHeader.parsedContent = getCSSPropsInStyleSheet(parsedContent);
}
return styleHeader;
});
});
function resolveChromePath() {
if (canAccess(process.env.CHROME_PATH)) {
return process.env.CHROME_PATH;
}
if (canAccess(process.env.LIGHTHOUSE_CHROMIUM_PATH)) {
log.warn('ChromeLauncher', 'LIGHTHOUSE_CHROMIUM_PATH is deprecated, use CHROME_PATH env variable instead.');
return process.env.LIGHTHOUSE_CHROMIUM_PATH;
}
return undefined;
}
/**
opts.fingerprint = ['{{ default }}', err.protocolMethod, err.protocolError];
}
return new Promise(resolve => {
Sentry.captureException(err, opts, () => resolve());
});
};
const context = Object.assign({
url: opts.url,
emulatedFormFactor: opts.flags.emulatedFormFactor,
throttlingMethod: opts.flags.throttlingMethod,
}, opts.flags.throttling);
Sentry.mergeContext({extra: Object.assign({}, opts.environmentData.extra, context)});
} catch (e) {
log.warn(
'sentry',
'Could not load raven library, errors will not be reported.'
);
}
}
}).catch(err => log.warn('Driver', err));
});
categoryIds.forEach(categoryId => {
if (!oldCategories[categoryId]) {
log.warn('config', `unrecognized category in 'onlyCategories': ${categoryId}`);
}
});