From fc8aa307562e805c2284c7817edaedfc96788d99 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 4 Dec 2021 17:22:36 +0100 Subject: [PATCH] lib/client: add generic error handling to roundtrip() --- lib/client.js | 86 +++++++++++++++++++++++++++------------------------ lib/irc.js | 4 +++ 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/lib/client.js b/lib/client.js index 894e991..c5c6652 100644 --- a/lib/client.js +++ b/lib/client.js @@ -52,10 +52,11 @@ let lastWhoxToken = 0; class IRCError extends Error { constructor(msg) { let text; - if (irc.isError(msg.command) && msg) { + if (msg.params.length > 0) { + // IRC errors have a human-readable message as last param text = msg.params[msg.params.length - 1]; } else { - text = `unknown error (${msg.command} ${msg.params.join(" ")})`; + text = `unknown error (${msg.command})`; } super(text); @@ -717,6 +718,8 @@ export default class Client extends EventTarget { /* Execute a command that expects a response. `done` is called with message * events until it returns a truthy value. */ roundtrip(msg, done) { + let cmd = msg.command; + let label; if (this.enabledCaps["labeled-response"]) { lastLabel++; @@ -735,6 +738,24 @@ export default class Client extends EventTarget { return; } + let isError = false; + switch (msg.command) { + case "FAIL": + isError = msg.params[0] === cmd; + break; + case irc.ERR_UNKNOWNERROR: + case irc.ERR_UNKNOWNCOMMAND: + case irc.ERR_NEEDMOREPARAMS: + case irc.RPL_TRYAGAIN: + isError = msg.params[1] === cmd; + break; + } + if (isError) { + removeEventListeners(); + reject(new IRCError(msg)); + return; + } + let result; try { result = done(msg); @@ -784,23 +805,18 @@ export default class Client extends EventTarget { } } - switch (msg.command) { - case "BATCH": - let enter = msg.params[0].startsWith("+"); - let name = msg.params[0].slice(1); - if (enter && msg.params[1] === batchType) { - batchName = name; - break; - } - if (!enter && name === batchName) { - return { ...this.batches.get(name), messages }; - } - break; - case "FAIL": - if (msg.params[0] === cmd) { - throw new IRCError(msg); - } - break; + if (msg.command !== "BATCH") { + return; + } + + let enter = msg.params[0].startsWith("+"); + let name = msg.params[0].slice(1); + if (enter && msg.params[1] === batchType) { + batchName = name; + return; + } + if (!enter && name === batchName) { + return { ...this.batches.get(name), messages }; } }); } @@ -950,20 +966,15 @@ export default class Client extends EventTarget { params: ["*", email || "*", password], }; return this.roundtrip(msg, (msg) => { - switch (msg.command) { - case "REGISTER": - let result = msg.params[0]; - return { - verificationRequired: result === "VERIFICATION_REQUIRED", - account: msg.params[1], - message: msg.params[2], - }; - case "FAIL": - if (msg.params[0] === "REGISTER") { - throw new IRCError(msg); - } - break; + if (msg.command !== "REGISTER") { + return; } + let result = msg.params[0]; + return { + verificationRequired: result === "VERIFICATION_REQUIRED", + account: msg.params[1], + message: msg.params[2], + }; }); } @@ -973,15 +984,10 @@ export default class Client extends EventTarget { params: [account, code], }; return this.roundtrip(msg, (msg) => { - switch (msg.command) { - case "VERIFY": - return { message: msg.params[2] }; - case "FAIL": - if (msg.params[0] === "VERIFY") { - throw new IRCError(msg); - } - break; + if (msg.command !== "VERIFY") { + return; } + return { message: msg.params[2] }; }); } } diff --git a/lib/irc.js b/lib/irc.js index 360b817..db130d5 100644 --- a/lib/irc.js +++ b/lib/irc.js @@ -5,6 +5,7 @@ export const RPL_CREATED = "003"; export const RPL_MYINFO = "004"; export const RPL_ISUPPORT = "005"; export const RPL_UMODEIS = "221"; +export const RPL_TRYAGAIN = "263"; export const RPL_AWAY = "301"; export const RPL_WHOISUSER = "311"; export const RPL_WHOISSERVER = "312"; @@ -31,11 +32,14 @@ export const RPL_ENDOFBANLIST = "368"; export const RPL_MOTD = "372"; export const RPL_MOTDSTART = "375"; export const RPL_ENDOFMOTD = "376"; +export const ERR_UNKNOWNERROR = "400"; export const ERR_NOSUCHNICK = "401"; +export const ERR_UNKNOWNCOMMAND = "421"; export const ERR_NOMOTD = "422"; export const ERR_ERRONEUSNICKNAME = "432"; export const ERR_NICKNAMEINUSE = "433"; export const ERR_NICKCOLLISION = "436"; +export const ERR_NEEDMOREPARAMS = "461"; export const ERR_NOPERMFORHOST = "463"; export const ERR_PASSWDMISMATCH = "464"; export const ERR_YOUREBANNEDCREEP = "465";