Better handle WS connection errors

This commit is contained in:
Declan Chidlow 2024-07-13 16:47:24 +08:00
parent 474986b990
commit d9d3726aa9

View file

@ -15,11 +15,15 @@ const wsEvents = new EventEmitter();
const { API_WS_URL, API_WS_TOKEN } = process.env;
const wsQueue: { [key: string]: string }[] = [];
let client: ws | undefined = undefined;
let retryCount = 0;
const MAX_RETRIES = 10;
const INITIAL_RETRY_DELAY = 3000;
type WSResponse = { success: false; error: string; statusCode?: number } | { success: true; [key: string]: any };
if (!API_WS_URL || !API_WS_TOKEN) logger.info("$API_WS_URL or $API_WS_TOKEN not found.");
else {
if (!API_WS_URL || !API_WS_TOKEN) {
logger.error("$API_WS_URL or $API_WS_TOKEN not found. Please set these environment variables.");
} else {
logger.info(`$API_WS_URL and $API_WS_TOKEN set; Connecting to ${API_WS_URL}`);
connect();
}
@ -29,7 +33,8 @@ function connect() {
client = new ws(API_WS_URL!, { headers: { authorization: API_WS_TOKEN! } });
client.once("open", () => {
logger.debug("WS connected");
logger.info("WebSocket connected successfully");
retryCount = 0;
if (wsQueue.length > 0) {
logger.debug(`Attempting to send ${wsQueue.length} queued WS messages`);
@ -44,13 +49,13 @@ function connect() {
client.once("close", () => {
client = undefined;
logger.warn(`WS closed, reconnecting in 3 seconds`);
setTimeout(connect, 3000);
retryConnection();
});
client.once("error", (err: Error) => {
client = undefined;
logger.warn(`WS: ${err}`);
logger.error(`WebSocket error: ${err.message}`);
retryConnection();
});
client.on("message", (msg: ws.Data) => {
@ -89,6 +94,19 @@ function wsSend(data: { [key: string]: any }) {
}
}
function retryConnection() {
if (retryCount >= MAX_RETRIES) {
logger.error(`Failed to connect after ${MAX_RETRIES} attempts. Please check your network and API_WS_URL.`);
return;
}
const delay = INITIAL_RETRY_DELAY * Math.pow(2, retryCount);
retryCount++;
logger.warn(`WebSocket disconnected. Attempting to reconnect in ${delay / 1000} seconds (Attempt ${retryCount} of ${MAX_RETRIES})`);
setTimeout(connect, delay);
}
wsEvents.on("req:test", (data: any, res: (data: any) => void) => {
res({ received: data });
});