Skip to content

Commit

Permalink
report: unknown details type (#9557)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorjclark authored Sep 14, 2019
1 parent 174fff7 commit 1a45e86
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 deletions.
26 changes: 21 additions & 5 deletions lighthouse-core/report/html/renderer/details-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ class DetailsRenderer {
return null;

default: {
// @ts-ignore tsc thinks this unreachable, but ts-ignore for error message just in case.
const detailsType = details.type;
throw new Error(`Unknown type: ${detailsType}`);
// @ts-ignore tsc thinks this is unreachable, but be forward compatible
// with new unexpected detail types.
return this._renderUnknown(details.type, details);
}
}
}
Expand Down Expand Up @@ -188,6 +188,22 @@ class DetailsRenderer {
return element;
}

/**
* @param {string} type
* @param {*} value
*/
_renderUnknown(type, value) {
// eslint-disable-next-line no-console
console.error(`Unknown details type: ${type}`, value);
const element = this._dom.createElement('details', 'lh-unknown');
this._dom.createChildOf(element, 'summary').textContent =
`We don't know how to render audit details of type \`${type}\`. ` +
'The Lighthouse version that collected this data is likely newer than the Lighthouse ' +
'version of the report renderer. Expand for the raw JSON.';
this._dom.createChildOf(element, 'pre').textContent = JSON.stringify(value, null, 2);
return element;
}

/**
* Render a details item value for embedding in a table. Renders the value
* based on the heading's valueType, unless the value itself has a `type`
Expand Down Expand Up @@ -218,7 +234,7 @@ class DetailsRenderer {
return this.renderTextURL(value.value);
}
default: {
throw new Error(`Unknown valueType: ${value.type}`);
return this._renderUnknown(value.type, value);
}
}
}
Expand Down Expand Up @@ -267,7 +283,7 @@ class DetailsRenderer {
}
}
default: {
throw new Error(`Unknown valueType: ${heading.valueType}`);
return this._renderUnknown(heading.valueType, value);
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions lighthouse-core/report/html/report-styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,11 @@
display: block;
}

.lh-unknown pre {
overflow: scroll;
border: solid 1px var(--color-gray-200);
}

.lh-text__url > a {
color: inherit;
text-decoration: none;
Expand Down
26 changes: 20 additions & 6 deletions lighthouse-core/test/report/html/renderer/details-renderer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,18 @@ describe('DetailsRenderer', () => {
assert.strictEqual(diagnosticEl, null);
});

it('throws on unknown details type', () => {
it('renders an unknown details type', () => {
// Disallowed by type system, but test that we get an error message out just in case.
const details = {
type: 'imaginary',
items: 5,
};

assert.throws(() => renderer.render(details), /^Error: Unknown type: imaginary$/);
const el = renderer.render(details);
const summaryEl = el.querySelector('summary');
expect(summaryEl.textContent)
.toContain('We don\'t know how to render audit details of type `imaginary`');
assert.strictEqual(el.lastChild.textContent, JSON.stringify(details, null, 2));
});
});

Expand Down Expand Up @@ -451,18 +455,23 @@ describe('DetailsRenderer', () => {
assert.strictEqual(codeItemEl.innerHTML, '<pre class="lh-code">invalid-url://example.com/</pre>');
});

it('throws on unknown heading itemType', () => {
it('renders an unknown heading itemType', () => {
// Disallowed by type system, but test that we get an error message out just in case.
const details = {
type: 'table',
headings: [{key: 'content', itemType: 'notRealValueType', text: 'Heading'}],
items: [{content: 'some string'}],
};

assert.throws(() => renderer.render(details), /^Error: Unknown valueType: notRealValueType$/);
const el = renderer.render(details);
const unknownEl = el.querySelector('td.lh-table-column--notRealValueType .lh-unknown');
const summaryEl = unknownEl.querySelector('summary');
expect(summaryEl.textContent)
.toContain('We don\'t know how to render audit details of type `notRealValueType`');
assert.strictEqual(unknownEl.lastChild.textContent, '"some string"');
});

it('throws on unknown item object type', () => {
it('renders an unknown item object type', () => {
// Disallowed by type system, but test that we get an error message out just in case.
const item = {
type: 'imaginaryItem',
Expand All @@ -475,7 +484,12 @@ describe('DetailsRenderer', () => {
items: [{content: item}],
};

assert.throws(() => renderer.render(details), /^Error: Unknown valueType: imaginaryItem$/);
const el = renderer.render(details);
const unknownEl = el.querySelector('td.lh-table-column--url .lh-unknown');
const summaryEl = unknownEl.querySelector('summary');
expect(summaryEl.textContent)
.toContain('We don\'t know how to render audit details of type `imaginaryItem`');
assert.strictEqual(unknownEl.lastChild.textContent, JSON.stringify(item, null, 2));
});

it('uses the item\'s type over the heading type', () => {
Expand Down

0 comments on commit 1a45e86

Please sign in to comment.