Repository: GoogleChrome/lighthouse
Pull request #6579 (2018-11-16 08:15:49)

core(gather): define new DNS failure LH Error
Seeing a lot of these errors. I think we want to expose them to the user individually.

paulirish: ptal
paulirish: @patrickhulce @exterkamp sg?

Patch:
diff --git a/lighthouse-core/gather/gather-runner.js b/lighthouse-core/gather/gather-runner.js
index 7c65e840b..50726d043 100644
--- a/lighthouse-core/gather/gather-runner.js
+++ b/lighthouse-core/gather/gather-runner.js
@@ -150,8 +150,19 @@ class GatherRunner {
     if (!mainRecord) {
       errorDef = LHError.errors.NO_DOCUMENT_REQUEST;
     } else if (mainRecord.failed) {
-      errorDef = {...LHError.errors.FAILED_DOCUMENT_REQUEST};
-      errorDef.message += ` ${mainRecord.localizedFailDescription}.`;
+      const netErr = mainRecord.localizedFailDescription;
+      // Match all resolution and DNS failures
+      // https://cs.chromium.org/chromium/src/net/base/net_error_list.h?rcl=cd62979b
+      if (
+        netErr === 'net::ERR_NAME_NOT_RESOLVED' ||
+        netErr === 'net::ERR_NAME_RESOLUTION_FAILED' ||
+        netErr.startsWith('net::ERR_DNS_')
+      ) {
+        errorDef = LHError.errors.DNS_FAILURE;
+      } else {
+        errorDef = {...LHError.errors.FAILED_DOCUMENT_REQUEST};
+        errorDef.message += ` ${netErr}.`;
+      }
     } else if (mainRecord.hasErrorStatusCode()) {
       errorDef = {...LHError.errors.ERRORED_DOCUMENT_REQUEST};
       errorDef.message += ` Status code: ${mainRecord.statusCode}.`;
diff --git a/lighthouse-core/lib/lh-error.js b/lighthouse-core/lib/lh-error.js
index 9b4049cf2..dbaae2b08 100644
--- a/lighthouse-core/lib/lh-error.js
+++ b/lighthouse-core/lib/lh-error.js
@@ -188,6 +188,13 @@ const ERRORS = {
     lhrRuntimeError: true,
   },
 
+  // DNS failure on main document (no resolution, timed out, etc)
+  DNS_FAILURE: {
+    code: 'DNS_FAILURE',
+    message: strings.dnsFailure,
+    lhrRuntimeError: true,
+  },
+
   // Hey! When adding a new error type, update lighthouse-result.proto too.
 };
 
diff --git a/lighthouse-core/lib/strings.js b/lighthouse-core/lib/strings.js
index ead92c977..3792cae3f 100644
--- a/lighthouse-core/lib/strings.js
+++ b/lighthouse-core/lib/strings.js
@@ -17,4 +17,5 @@ module.exports = {
   requestContentTimeout: 'Fetching resource content has exceeded the allotted time',
   urlInvalid: `The URL you have provided appears to be invalid.`,
   protocolTimeout: `Waiting for DevTools protocol response has exceeded the allotted time.`,
+  dnsFailure: `DNS servers could not resolve the provided domain.`,
 };
diff --git a/proto/lighthouse-result.proto b/proto/lighthouse-result.proto
index a34ce7abb..0af762379 100644
--- a/proto/lighthouse-result.proto
+++ b/proto/lighthouse-result.proto
@@ -49,6 +49,8 @@ enum LighthouseError {
   PROTOCOL_TIMEOUT = 17;
   // Used when the page is not responding after maxWaitForLoad.
   PAGE_HUNG = 18;
+  // DNS failure on main document (no resolution, timed out, etc)
+  DNS_FAILURE = 19;
 }
 
 // The overarching Lighthouse Response object (LHR)


Test patch:
diff --git a/lighthouse-core/test/gather/gather-runner-test.js b/lighthouse-core/test/gather/gather-runner-test.js
index 2b773a8d8..c302d5db3 100644
--- a/lighthouse-core/test/gather/gather-runner-test.js
+++ b/lighthouse-core/test/gather/gather-runner-test.js
@@ -679,6 +679,18 @@ describe('GatherRunner', function() {
       assert.equal(error.code, 'ERRORED_DOCUMENT_REQUEST');
       assert.ok(/^Lighthouse was unable to reliably load/.test(error.friendlyMessage));
     });
+
+    it('fails when page domain doesn\'t resolve', () => {
+      const url = 'http://the-page.com';
+      const mainRecord = new NetworkRequest();
+      mainRecord.url = url;
+      mainRecord.failed = true;
+      mainRecord.localizedFailDescription = 'net::ERR_NAME_NOT_RESOLVED';
+      const error = GatherRunner.getPageLoadError(url, [mainRecord]);
+      assert.equal(error.message, 'DNS_FAILURE');
+      assert.equal(error.code, 'DNS_FAILURE');
+      assert.ok(/^DNS servers could not resolve/.test(error.friendlyMessage));
+    });
   });
 
   describe('#assertNoSecurityIssues', () => {
@@ -1059,7 +1071,7 @@ describe('GatherRunner', function() {
         config: new Config({}),
       }).then(artifacts => {
         assert.equal(artifacts.LighthouseRunWarnings.length, 1);
-        assert.ok(/unable.*load the page/.test(artifacts.LighthouseRunWarnings[0]));
+        assert.ok(/DNS servers could not resolve/.test(artifacts.LighthouseRunWarnings[0]));
       });
     });