aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-client/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-client/src')
-rw-r--r--packages/meshbay-client/src/main.js14
1 files changed, 14 insertions, 0 deletions
diff --git a/packages/meshbay-client/src/main.js b/packages/meshbay-client/src/main.js
index 8e11f1f..6228189 100644
--- a/packages/meshbay-client/src/main.js
+++ b/packages/meshbay-client/src/main.js
@@ -252,6 +252,10 @@ function publicKeyB64(privateKey) {
// full-screen is the whole list.
const GRANTED_PERMISSIONS = new Set(['fullscreen']);
+// No hub call is still going to be answered after this. The hub's longest is
+// signaling a WebRTC offer, which gives up at fifteen seconds of its own.
+const HUB_FETCH_TIMEOUT_MS = 30000;
+
// ── Window ──────────────────────────────────────────────────────────────────
let mainWindow = null;
@@ -414,8 +418,18 @@ function registerBridge() {
method: (init && init.method) || 'GET',
headers: (init && init.headers) || {},
body: (init && init.body) || undefined,
+ // Node's fetch waits as long as the OS lets it, which for a host that
+ // accepts a connection and then says nothing is minutes. The hub's own
+ // longest call is signaling, which gives up at fifteen seconds, so
+ // anything past this is not an answer that is still coming.
+ signal: AbortSignal.timeout(HUB_FETCH_TIMEOUT_MS),
});
} catch (e) {
+ if (e && (e.name === 'TimeoutError' || e.name === 'AbortError')) {
+ throw new Error(
+ `${target.origin} accepted the connection but did not answer within `
+ + `${Math.round(HUB_FETCH_TIMEOUT_MS / 1000)}s.`);
+ }
// Node's fetch says "fetch failed" for everything from a refused
// connection to a TLS mismatch, which tells a person nothing at all.
throw new Error(describeUnreachable(target.origin, e));