From 0217ea90e205b21ee4bb0d7ea8d37fa6a22d98f6 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 5 Jun 2021 15:05:03 +0200 Subject: [PATCH] Fixed error handling --- src/locutus.ts | 24 ++++++++++++------------ src/usimp.ts | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/locutus.ts b/src/locutus.ts index f92f8dd..10b3df5 100644 --- a/src/locutus.ts +++ b/src/locutus.ts @@ -15,11 +15,11 @@ export class App { this.session = null; const main = document.getElementsByTagName("main")[0]; - if (!main) throw Error("Element
not found"); + if (!main) throw new Error("Element
not found"); this.main = main; const windows = document.getElementById("windows"); - if (!windows) throw Error("Element #windows not found"); + if (!windows) throw new Error("Element #windows not found"); this.windows = windows; window.addEventListener("hashchange", event => { @@ -84,9 +84,9 @@ export class App { domain = await USIMP.Domain.fromName(domainName); } catch (error) { if (error instanceof DOMException) { - throw Error("Connection timed out"); + throw new Error("Connection timed out"); } else { - throw Error("Invalid USIMP domain"); + throw new Error("Invalid USIMP domain"); } } @@ -101,7 +101,7 @@ export class App { this.setHash("/"); } else { console.error(response.error); - throw Error(response.error.message || response.error.code); + throw new Error(response.error.message || response.error.code); } } @@ -143,7 +143,7 @@ export class App { msg.innerText = message; const chat = this.main.getElementsByClassName("chat-history")[0]; - if (!chat) throw Error("Element .chat-history not found"); + if (!chat) throw new Error("Element .chat-history not found"); chat.appendChild(msg); chat.scrollTop = chat.scrollHeight; @@ -163,7 +163,7 @@ export class App { `; const form = win.getElementsByTagName("form")[0]; - if (!form) throw Error("Element
not found"); + if (!form) throw new Error("Element not found"); form.addEventListener("submit", async event => { event.preventDefault(); @@ -201,14 +201,14 @@ export class App { this.windows.appendChild(win); const domain = document.getElementsByName("domain")[0]; - if (!domain) throw Error("Element name=domain not found"); + if (!domain) throw new Error("Element name=domain not found"); domain.addEventListener("input", (event) => { domain.removeAttribute("invalid"); }); const account = document.getElementsByName("account")[0]; - if (!account) throw Error("Element name=account not found"); + if (!account) throw new Error("Element name=account not found"); account.addEventListener("input", (event) => { account.removeAttribute("invalid"); @@ -218,7 +218,7 @@ export class App { } setupMain() { - if (!this.session) throw Error("Invalid state"); + if (!this.session) throw new Error("Invalid state"); this.main.innerHTML = `
@@ -229,11 +229,11 @@ export class App {
`; const input = document.getElementsByTagName("input")[0]; - if (!input) throw Error("Element not found"); + if (!input) throw new Error("Element not found"); input.addEventListener("keyup", async event => { if (event.key === "Enter" && input.value.length > 0) { - if (!this.session) throw Error("No session found"); + if (!this.session) throw new Error("No session found"); this.addMessage(input.value); const val = input.value; diff --git a/src/usimp.ts b/src/usimp.ts index d2105f7..da72a4a 100644 --- a/src/usimp.ts +++ b/src/usimp.ts @@ -67,7 +67,7 @@ export class Domain { clearTimeout(timer); if (!response.ok) { - throw Error("Invalid response"); + throw new Error("Invalid response"); } const data: WellKnownJson = await response.json(); @@ -75,10 +75,10 @@ export class Domain { } chooseDomainServer(): DomainServer { - if (this.servers.length === 0) throw Error("No domain servers specified"); + if (this.servers.length === 0) throw new Error("No domain servers specified"); const servers = this.servers.filter(srv => !this.invalidServers.map(srv => srv.id).includes(srv.id)); - if (servers.length === 0) throw Error("No domain servers reachable"); + if (servers.length === 0) throw new Error("No domain servers reachable"); if (servers.length === 1 && servers[0]) return servers[0]; const priority = servers.reduce((min, srv) => Math.min(min, srv.priority), Infinity); @@ -94,7 +94,7 @@ export class Domain { if (w < accumulator) return srv; } - throw Error("Domain server selection did not work correctly"); + throw new Error("Domain server selection did not work correctly"); } } @@ -194,20 +194,30 @@ export class Session { return undefined; } - waitForWebSocket() { - if (this.websocket === null) throw Error("websocket not initialized"); + waitForWebSocket(timeout: number) { + if (this.websocket === null) throw new Error("websocket not initialized"); return new Promise((resolve, reject) => { if (this.websocket?.readyState === this.websocket?.OPEN) { resolve(); } else { const handlerOpen = () => { + clearTimeout(timer); this.websocket?.removeEventListener("open", handlerOpen); + this.websocket?.removeEventListener("error", handlerError); resolve(); }; const handlerError = (error: any) => { + clearTimeout(timer); + this.websocket?.removeEventListener("open", handlerOpen); this.websocket?.removeEventListener("error", handlerError); reject(error); } + const handlerTimeout = () => { + this.websocket?.removeEventListener("open", handlerOpen); + this.websocket?.removeEventListener("error", handlerError); + reject(new Error("timeout")); + } + const timer = setTimeout(handlerTimeout, timeout); this.websocket?.addEventListener("open", handlerOpen); this.websocket?.addEventListener("error", handlerError); } @@ -215,7 +225,7 @@ export class Session { } waitForWebSocketResponse(req_nr: number, timeout: number) { - if (this.websocket === null) throw Error("websocket not initialized"); + if (this.websocket === null) throw new Error("websocket not initialized"); return new Promise((resolve, reject) => { const handlerMsg = (msg: any) => { const data = JSON.parse(msg.data); @@ -235,7 +245,7 @@ export class Session { const handlerTimeout = () => { this.websocket?.removeEventListener("message", handlerMsg); this.websocket?.removeEventListener("error", handlerError); - reject(Error("timeout")); + reject(new Error("timeout")); } const timer = setTimeout(handlerTimeout, timeout); this.websocket?.addEventListener("message", handlerMsg); @@ -251,6 +261,8 @@ export class Session { const req_nr = this.numRequests; const startTime = performance.now(); + await this.waitForWebSocket(timeout); + let response; if (cb === null) { response = this.waitForWebSocketResponse(req_nr, timeout); @@ -263,7 +275,6 @@ export class Session { }); } - await this.waitForWebSocket(); await this.websocket.send(JSON.stringify({ 'request_nr': req_nr, 'endpoint': endpoint, @@ -280,7 +291,7 @@ export class Session { } else { return null; // TODO subscription id } - } else { + } else if (this.httpBaseUrl) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeout); @@ -305,9 +316,16 @@ export class Session { const endTime = performance.now(); responseData.duration = endTime - startTime; return responseData; + } else { + throw new Error("No domain server chosen"); } } catch (error) { console.error(error); + if (this.websocket !== null) { + this.websocket.close(); + this.websocket = null; + } + this.httpBaseUrl = null; if (this.server !== null) { this.domain.invalidServers.push(this.server); this.server = null;