lib/client: use Error objects for error events

This commit is contained in:
Simon Ser 2021-12-06 23:09:30 +01:00
parent f9ec578fce
commit 31b293fa03
2 changed files with 31 additions and 24 deletions

View file

@ -317,8 +317,21 @@ export default class App extends Component {
} }
} }
showError(msg) { showError(err) {
this.setState({ error: String(msg) }); console.error("App error: ", err);
let text;
if (err instanceof Error) {
let l = [];
while (err) {
l.push(err.message);
err = err.cause;
}
text = l.join(": ");
} else {
text = String(err);
}
this.setState({ error: text });
lastErrorID++; lastErrorID++;
return lastErrorID; return lastErrorID;
} }

View file

@ -126,7 +126,7 @@ export default class Client extends EventTarget {
} catch (err) { } catch (err) {
console.error("Failed to create connection:", err); console.error("Failed to create connection:", err);
setTimeout(() => { setTimeout(() => {
this.dispatchEvent(new CustomEvent("error", { detail: "Failed to create connection: " + err })); this.dispatchError(new Error("Failed to create connection", { cause: err }));
this.setStatus(Client.Status.DISCONNECTED); this.setStatus(Client.Status.DISCONNECTED);
}, 0); }, 0);
return; return;
@ -137,7 +137,7 @@ export default class Client extends EventTarget {
try { try {
this.handleMessage(event); this.handleMessage(event);
} catch (err) { } catch (err) {
this.dispatchEvent(new CustomEvent("error", { detail: err })); this.dispatchError(err);
this.disconnect(); this.disconnect();
} }
}); });
@ -146,7 +146,7 @@ export default class Client extends EventTarget {
console.log("Connection closed (code: " + event.code + ")"); console.log("Connection closed (code: " + event.code + ")");
if (event.code !== NORMAL_CLOSURE && event.code !== GOING_AWAY) { if (event.code !== NORMAL_CLOSURE && event.code !== GOING_AWAY) {
this.dispatchEvent(new CustomEvent("error", { detail: "Connection error" })); this.dispatchError(new Error("Connection error"));
} }
this.ws = null; this.ws = null;
@ -202,6 +202,10 @@ export default class Client extends EventTarget {
this.dispatchEvent(new CustomEvent("status")); this.dispatchEvent(new CustomEvent("status"));
} }
dispatchError(err) {
this.dispatchEvent(new CustomEvent("error", { detail: err }));
}
handleOpen() { handleOpen() {
console.log("Connection opened"); console.log("Connection opened");
this.setStatus(Client.Status.REGISTERING); this.setStatus(Client.Status.REGISTERING);
@ -264,7 +268,7 @@ export default class Client extends EventTarget {
switch (msg.command) { switch (msg.command) {
case irc.RPL_WELCOME: case irc.RPL_WELCOME:
if (this.params.saslPlain && !this.supportsCap) { if (this.params.saslPlain && !this.supportsCap) {
this.dispatchEvent(new CustomEvent("error", { detail: "Server doesn't support SASL PLAIN" })); this.dispatchError(new Error("Server doesn't support SASL PLAIN"));
this.disconnect(); this.disconnect();
return; return;
} }
@ -303,7 +307,7 @@ export default class Client extends EventTarget {
// Both PLAIN and EXTERNAL expect an empty challenge // Both PLAIN and EXTERNAL expect an empty challenge
let challengeStr = msg.params[0]; let challengeStr = msg.params[0];
if (challengeStr != "+") { if (challengeStr != "+") {
this.dispatchEvent(new CustomEvent("error", { detail: "Expected an empty challenge, got: " + challengeStr })); this.dispatchError(new Error("Expected an empty challenge, got: " + challengeStr));
this.send({ command: "AUTHENTICATE", params: ["*"] }); this.send({ command: "AUTHENTICATE", params: ["*"] });
} }
break; break;
@ -362,9 +366,7 @@ export default class Client extends EventTarget {
} }
break; break;
case "ERROR": case "ERROR":
this.dispatchEvent(new CustomEvent("error", { this.dispatchError(new IRCError(msg));
detail: "Fatal IRC error: " + msg.params[0],
}));
this.disconnect(); this.disconnect();
break; break;
case irc.ERR_PASSWDMISMATCH: case irc.ERR_PASSWDMISMATCH:
@ -374,9 +376,7 @@ export default class Client extends EventTarget {
case irc.ERR_UNAVAILRESOURCE: case irc.ERR_UNAVAILRESOURCE:
case irc.ERR_NOPERMFORHOST: case irc.ERR_NOPERMFORHOST:
case irc.ERR_YOUREBANNEDCREEP: case irc.ERR_YOUREBANNEDCREEP:
this.dispatchEvent(new CustomEvent("error", { this.dispatchError(new IRCError(msg));
detail: "Error (" + msg.command + "): " + msg.params[msg.params.length - 1],
}));
if (this.status != Client.Status.REGISTERED) { if (this.status != Client.Status.REGISTERED) {
this.disconnect(); this.disconnect();
} }
@ -387,15 +387,13 @@ export default class Client extends EventTarget {
} }
let reason = msg.params[msg.params.length - 1]; let reason = msg.params[msg.params.length - 1];
if (msg.params[0] === "BOUNCER" && msg.params[2] === "BIND") { if (msg.params[0] === "BOUNCER" && msg.params[2] === "BIND") {
this.dispatchEvent(new CustomEvent("error", { this.dispatchError(new Error("Failed to bind to bouncer network", {
detail: "Failed to bind to bouncer network: " + reason, cause: new IRCError(msg),
})); }));
this.disconnect(); this.disconnect();
} }
if (msg.params[1] === "ACCOUNT_REQUIRED") { if (msg.params[1] === "ACCOUNT_REQUIRED") {
this.dispatchEvent(new CustomEvent("error", { this.dispatchError(new IRCError(msg));
detail: reason,
}));
this.disconnect(); this.disconnect();
} }
break; break;
@ -635,12 +633,8 @@ export default class Client extends EventTarget {
} else if (this.params.saslExternal) { } else if (this.params.saslExternal) {
promise = this.authenticate("EXTERNAL"); promise = this.authenticate("EXTERNAL");
} }
(promise || Promise.resolve()).catch((msg) => { (promise || Promise.resolve()).catch((err) => {
if (msg.command) { this.dispatchError(err);
this.dispatchEvent(new CustomEvent("error", {
detail: "Authentication error (SASL " + msg.command + "): " + msg.params[1],
}));
}
this.disconnect(); this.disconnect();
}); });
} }