Fixed error handling

This commit is contained in:
2021-06-05 15:05:03 +02:00
parent 5b2deaa346
commit 0217ea90e2
2 changed files with 40 additions and 22 deletions

View File

@ -15,11 +15,11 @@ export class App {
this.session = null; this.session = null;
const main = document.getElementsByTagName("main")[0]; const main = document.getElementsByTagName("main")[0];
if (!main) throw Error("Element <main> not found"); if (!main) throw new Error("Element <main> not found");
this.main = main; this.main = main;
const windows = document.getElementById("windows"); 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; this.windows = windows;
window.addEventListener("hashchange", event => { window.addEventListener("hashchange", event => {
@ -84,9 +84,9 @@ export class App {
domain = await USIMP.Domain.fromName(domainName); domain = await USIMP.Domain.fromName(domainName);
} catch (error) { } catch (error) {
if (error instanceof DOMException) { if (error instanceof DOMException) {
throw Error("Connection timed out"); throw new Error("Connection timed out");
} else { } else {
throw Error("Invalid USIMP domain"); throw new Error("Invalid USIMP domain");
} }
} }
@ -101,7 +101,7 @@ export class App {
this.setHash("/"); this.setHash("/");
} else { } else {
console.error(response.error); 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; msg.innerText = message;
const chat = this.main.getElementsByClassName("chat-history")[0]; 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.appendChild(msg);
chat.scrollTop = chat.scrollHeight; chat.scrollTop = chat.scrollHeight;
@ -163,7 +163,7 @@ export class App {
</form>`; </form>`;
const form = win.getElementsByTagName("form")[0]; const form = win.getElementsByTagName("form")[0];
if (!form) throw Error("Element <form> not found"); if (!form) throw new Error("Element <form> not found");
form.addEventListener("submit", async event => { form.addEventListener("submit", async event => {
event.preventDefault(); event.preventDefault();
@ -201,14 +201,14 @@ export class App {
this.windows.appendChild(win); this.windows.appendChild(win);
const domain = document.getElementsByName("domain")[0]; 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.addEventListener("input", (event) => {
domain.removeAttribute("invalid"); domain.removeAttribute("invalid");
}); });
const account = document.getElementsByName("account")[0]; 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.addEventListener("input", (event) => {
account.removeAttribute("invalid"); account.removeAttribute("invalid");
@ -218,7 +218,7 @@ export class App {
} }
setupMain() { setupMain() {
if (!this.session) throw Error("Invalid state"); if (!this.session) throw new Error("Invalid state");
this.main.innerHTML = ` this.main.innerHTML = `
<div class="chat"> <div class="chat">
@ -229,11 +229,11 @@ export class App {
</div>`; </div>`;
const input = document.getElementsByTagName("input")[0]; const input = document.getElementsByTagName("input")[0];
if (!input) throw Error("Element <input> not found"); if (!input) throw new Error("Element <input> not found");
input.addEventListener("keyup", async event => { input.addEventListener("keyup", async event => {
if (event.key === "Enter" && input.value.length > 0) { 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); this.addMessage(input.value);
const val = input.value; const val = input.value;

View File

@ -67,7 +67,7 @@ export class Domain {
clearTimeout(timer); clearTimeout(timer);
if (!response.ok) { if (!response.ok) {
throw Error("Invalid response"); throw new Error("Invalid response");
} }
const data: WellKnownJson = await response.json(); const data: WellKnownJson = await response.json();
@ -75,10 +75,10 @@ export class Domain {
} }
chooseDomainServer(): DomainServer { 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)); 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]; if (servers.length === 1 && servers[0]) return servers[0];
const priority = servers.reduce((min, srv) => Math.min(min, srv.priority), Infinity); const priority = servers.reduce((min, srv) => Math.min(min, srv.priority), Infinity);
@ -94,7 +94,7 @@ export class Domain {
if (w < accumulator) return srv; 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; return undefined;
} }
waitForWebSocket() { waitForWebSocket(timeout: number) {
if (this.websocket === null) throw Error("websocket not initialized"); if (this.websocket === null) throw new Error("websocket not initialized");
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
if (this.websocket?.readyState === this.websocket?.OPEN) { if (this.websocket?.readyState === this.websocket?.OPEN) {
resolve(); resolve();
} else { } else {
const handlerOpen = () => { const handlerOpen = () => {
clearTimeout(timer);
this.websocket?.removeEventListener("open", handlerOpen); this.websocket?.removeEventListener("open", handlerOpen);
this.websocket?.removeEventListener("error", handlerError);
resolve(); resolve();
}; };
const handlerError = (error: any) => { const handlerError = (error: any) => {
clearTimeout(timer);
this.websocket?.removeEventListener("open", handlerOpen);
this.websocket?.removeEventListener("error", handlerError); this.websocket?.removeEventListener("error", handlerError);
reject(error); 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("open", handlerOpen);
this.websocket?.addEventListener("error", handlerError); this.websocket?.addEventListener("error", handlerError);
} }
@ -215,7 +225,7 @@ export class Session {
} }
waitForWebSocketResponse(req_nr: number, timeout: number) { 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<any>((resolve, reject) => { return new Promise<any>((resolve, reject) => {
const handlerMsg = (msg: any) => { const handlerMsg = (msg: any) => {
const data = JSON.parse(msg.data); const data = JSON.parse(msg.data);
@ -235,7 +245,7 @@ export class Session {
const handlerTimeout = () => { const handlerTimeout = () => {
this.websocket?.removeEventListener("message", handlerMsg); this.websocket?.removeEventListener("message", handlerMsg);
this.websocket?.removeEventListener("error", handlerError); this.websocket?.removeEventListener("error", handlerError);
reject(Error("timeout")); reject(new Error("timeout"));
} }
const timer = setTimeout(handlerTimeout, timeout); const timer = setTimeout(handlerTimeout, timeout);
this.websocket?.addEventListener("message", handlerMsg); this.websocket?.addEventListener("message", handlerMsg);
@ -251,6 +261,8 @@ export class Session {
const req_nr = this.numRequests; const req_nr = this.numRequests;
const startTime = performance.now(); const startTime = performance.now();
await this.waitForWebSocket(timeout);
let response; let response;
if (cb === null) { if (cb === null) {
response = this.waitForWebSocketResponse(req_nr, timeout); response = this.waitForWebSocketResponse(req_nr, timeout);
@ -263,7 +275,6 @@ export class Session {
}); });
} }
await this.waitForWebSocket();
await this.websocket.send(JSON.stringify({ await this.websocket.send(JSON.stringify({
'request_nr': req_nr, 'request_nr': req_nr,
'endpoint': endpoint, 'endpoint': endpoint,
@ -280,7 +291,7 @@ export class Session {
} else { } else {
return null; // TODO subscription id return null; // TODO subscription id
} }
} else { } else if (this.httpBaseUrl) {
const controller = new AbortController(); const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), timeout); const timer = setTimeout(() => controller.abort(), timeout);
@ -305,9 +316,16 @@ export class Session {
const endTime = performance.now(); const endTime = performance.now();
responseData.duration = endTime - startTime; responseData.duration = endTime - startTime;
return responseData; return responseData;
} else {
throw new Error("No domain server chosen");
} }
} catch (error) { } catch (error) {
console.error(error); console.error(error);
if (this.websocket !== null) {
this.websocket.close();
this.websocket = null;
}
this.httpBaseUrl = null;
if (this.server !== null) { if (this.server !== null) {
this.domain.invalidServers.push(this.server); this.domain.invalidServers.push(this.server);
this.server = null; this.server = null;