Skip to content
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

core: remove recoverOrThrow / err.fatal #6343

Merged
merged 4 commits into from
Oct 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 5 additions & 20 deletions lighthouse-core/gather/gather-runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,20 +130,6 @@ class GatherRunner {
});
}

/**
* Test any error output from the promise, absorbing non-fatal errors and
* throwing on fatal ones so that run is stopped.
* @param {Promise<*>} promise
* @return {Promise<void>}
*/
static recoverOrThrow(promise) {
return promise.catch(err => {
if (err.fatal) {
throw err;
}
});
}

/**
* Returns an error if the original network request failed or wasn't found.
* @param {string} url The URL of the original requested page.
Expand Down Expand Up @@ -197,7 +183,7 @@ class GatherRunner {
passContext.options = gathererDefn.options || {};
const artifactPromise = Promise.resolve().then(_ => gatherer.beforePass(passContext));
gathererResults[gatherer.name] = [artifactPromise];
await GatherRunner.recoverOrThrow(artifactPromise);
await artifactPromise.catch(() => {});
}
}

Expand Down Expand Up @@ -241,7 +227,7 @@ class GatherRunner {
const gathererResult = gathererResults[gatherer.name] || [];
gathererResult.push(artifactPromise);
gathererResults[gatherer.name] = gathererResult;
await GatherRunner.recoverOrThrow(artifactPromise);
await artifactPromise.catch(() => {});
}
}

Expand Down Expand Up @@ -308,7 +294,7 @@ class GatherRunner {
const gathererResult = gathererResults[gatherer.name] || [];
gathererResult.push(artifactPromise);
gathererResults[gatherer.name] = gathererResult;
await GatherRunner.recoverOrThrow(artifactPromise);
await artifactPromise.catch(() => {});
log.verbose('statusEnd', status);
}

Expand All @@ -319,7 +305,7 @@ class GatherRunner {
/**
* Takes the results of each gatherer phase for each gatherer and uses the
* last produced value (that's not undefined) as the artifact for that
* gatherer. If a non-fatal error was rejected from a gatherer phase,
* gatherer. If an error was rejected from a gatherer phase,
* uses that error object as the artifact instead.
* @param {Partial<GathererResults>} gathererResults
* @param {LH.BaseArtifacts} baseArtifacts
Expand All @@ -341,8 +327,7 @@ class GatherRunner {
// Typecast pretends artifact always provided here, but checked below for top-level `throw`.
gathererArtifacts[gathererName] = /** @type {NonVoid<PhaseResult>} */ (artifact);
} catch (err) {
// An error result must be non-fatal to not have caused an exit by now,
// so return it to runner to handle turning it into an error audit.
// Return error to runner to handle turning it into an error audit.
gathererArtifacts[gathererName] = err;
}

Expand Down
5 changes: 2 additions & 3 deletions lighthouse-core/gather/gatherers/gatherer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
* method. All methods can return the artifact value directly or return a
* Promise that resolves to that value.
*
* If an Error is thrown (or a Promise that rejects on an Error), the
* GatherRunner will check for a `fatal` property on the Error. If not set to
* `true`, the runner will treat it as an error internal to the gatherer and
* If an Error is thrown (or a Promise that rejects on an Error),
* the runner will treat it as an error internal to the gatherer and
* continue execution of any remaining gatherers.
*/
class Gatherer {
Expand Down
8 changes: 2 additions & 6 deletions lighthouse-core/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,7 @@ class Runner {
throw new Error(`Required ${artifactName} gatherer did not run.`);
}

// If artifact was an error, it must be non-fatal (or gatherRunner would
// have thrown). Output error result on behalf of audit.
// 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.
Expand Down Expand Up @@ -286,12 +285,9 @@ class Runner {
auditResult = Audit.generateAuditResult(audit, product);
} catch (err) {
log.warn(audit.meta.id, `Caught exception: ${err.message}`);
if (err.fatal) {
throw err;
}

Sentry.captureException(err, {tags: {audit: audit.meta.id}, level: 'error'});
// Non-fatal error become error audit result.
// Errors become error audit result.
const errorMessage = err.friendlyMessage ?
`${err.friendlyMessage} (${err.message})` :
`Audit error: ${err.message}`;
Expand Down
34 changes: 1 addition & 33 deletions lighthouse-core/test/gather/gather-runner-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,7 @@ describe('GatherRunner', function() {
});
});

it('supports sync and async throwing of non-fatal errors from gatherers', () => {
it('supports sync and async throwing of errors from gatherers', () => {
const gatherers = [
// sync
new class BeforeSync extends Gatherer {
Expand Down Expand Up @@ -974,38 +974,6 @@ describe('GatherRunner', function() {
});
});

it('rejects if a gatherer returns a fatal error', () => {
const errorMessage = 'Gather Failed in pass()';
const err = new Error(errorMessage);
err.fatal = true;
const gatherers = [
// sync
new class GathererSuccess extends Gatherer {
afterPass() {
return 1;
}
}(),
new class GathererFailure extends Gatherer {
pass() {
return Promise.reject(err);
}
},
].map(instance => ({instance}));
const passes = [{
blankDuration: 0,
gatherers,
}];

return GatherRunner.run(passes, {
driver: fakeDriver,
requestedUrl: 'https://example.com',
settings: {},
config: new Config({}),
}).then(
_ => assert.ok(false),
err => assert.strictEqual(err.message, errorMessage));
});

it('rejects if a gatherer does not provide an artifact', () => {
const passes = [{
blankDuration: 0,
Expand Down
29 changes: 2 additions & 27 deletions lighthouse-core/test/runner-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ describe('Runner', () => {

// TODO: need to support save/load of artifact errors.
// See https://github.com/GoogleChrome/lighthouse/issues/4984
it.skip('outputs an error audit result when required artifact was a non-fatal Error', () => {
it.skip('outputs an error audit result when required artifact was an Error', () => {
const errorMessage = 'blurst of times';
const artifactError = new Error(errorMessage);

Expand Down Expand Up @@ -326,7 +326,7 @@ describe('Runner', () => {
requiredArtifacts: [],
};

it('produces an error audit result when an audit throws a non-fatal Error', () => {
it('produces an error audit result when an audit throws an Error', () => {
const errorMessage = 'Audit yourself';
const config = new Config({
settings: {
Expand All @@ -351,31 +351,6 @@ describe('Runner', () => {
assert.ok(auditResult.errorMessage.includes(errorMessage));
});
});

it('rejects if an audit throws a fatal error', () => {
const errorMessage = 'Uh oh';
const config = new Config({
settings: {
auditMode: __dirname + '/fixtures/artifacts/empty-artifacts/',
},
audits: [
class FatalThrowyAudit extends Audit {
static get meta() {
return testAuditMeta;
}
static audit() {
const fatalError = new Error(errorMessage);
fatalError.fatal = true;
throw fatalError;
}
},
],
});

return Runner.run({}, {config}).then(
_ => assert.ok(false),
err => assert.strictEqual(err.message, errorMessage));
});
});

it('accepts devtoolsLog in artifacts', () => {
Expand Down