diff --git a/packages/app/src/components/connection-failure-copy.test.ts b/packages/app/src/components/connection-failure-copy.test.ts index 21cfcd40e5..de78ba43eb 100644 --- a/packages/app/src/components/connection-failure-copy.test.ts +++ b/packages/app/src/components/connection-failure-copy.test.ts @@ -28,6 +28,23 @@ function failure(message: string) { } describe("direct connection failure copy", () => { + it.each([ + "paseo-qa-nonexistent.invalid", + "ssl-paseo-qa.invalid", + "tls-paseo-qa.invalid", + "certificate-paseo-qa.invalid", + ])( + "identifies Android DNS failures for %s without treating the hostname as TLS evidence", + (host) => { + const message = `Unable to resolve host "${host}": No address associated with hostname`; + expect(failure(message)).toEqual({ + title: "Failed: tcp://example.test:443?ssl=true", + detail: labels.hostNotFound, + raw: `transport error — ${message}`, + }); + }, + ); + it("identifies Android certificate validation errors without calling them DNS failures", () => { const message = "java.security.cert.CertPathValidatorException: Trust anchor for certification path not found."; @@ -43,6 +60,7 @@ describe("direct connection failure copy", () => { ["SSL handshake failed", labels.tlsError], ["TLS handshake failed", labels.tlsError], ["getaddrinfo ENOTFOUND example.test", labels.hostNotFound], + ["getaddrinfo ENOTFOUND ssl.example.test", labels.hostNotFound], ["Host not found", labels.hostNotFound], ["connect ECONNREFUSED", labels.refused], ["connection timed out", labels.timedOut], diff --git a/packages/app/src/components/connection-failure-copy.ts b/packages/app/src/components/connection-failure-copy.ts index 1491ed01d8..e1ad2f203c 100644 --- a/packages/app/src/components/connection-failure-copy.ts +++ b/packages/app/src/components/connection-failure-copy.ts @@ -83,6 +83,8 @@ export function buildConnectionFailureCopy(input: { rawLower.includes("err_connection_refused") ) { detail = labels.refused; + } else if (rawLower.includes("unable to resolve host") || rawLower.includes("enotfound")) { + detail = labels.hostNotFound; } else if ( rawLower.includes("certificate") || rawLower.includes("certpathvalidator") || @@ -91,7 +93,7 @@ export function buildConnectionFailureCopy(input: { rawLower.includes("ssl") ) { detail = labels.tlsError; - } else if (rawLower.includes("enotfound") || rawLower.includes("not found")) { + } else if (rawLower.includes("not found")) { detail = labels.hostNotFound; } else if (rawLower.includes("ehostunreach") || rawLower.includes("host is unreachable")) { detail = labels.hostUnreachable;