TXBOX - refactor: update package configuration and improve error handling

- Changed package.json to use "tsx" instead of "ts-node" for development.
- Updated "@whiskeysockets/baileys" dependency to version 6.7.24.
- Added error handling for unhandled rejections and uncaught exceptions in server.ts.
- Implemented a reconnect mechanism for WhatsApp connection failures.
- Updated tsconfig.json to use "NodeNext" module and resolution for ESM compatibility.
This commit is contained in:
2026-10-06 15:39:28 -03:00
parent 0d6231a02e
commit 1438585a0a
4 changed files with 1436 additions and 2240 deletions
+1390 -2234
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -2,8 +2,9 @@
"name": "txbot",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"dev": "ts-node src/server.ts",
"dev": "tsx src/server.ts",
"build": "tsc",
"start": "node dist/server.js"
},
@@ -12,14 +13,14 @@
"license": "ISC",
"description": "",
"dependencies": {
"@whiskeysockets/baileys": "6.17.16",
"@whiskeysockets/baileys": "6.7.24",
"express": "^5.1.0",
"qrcode": "^1.5.4"
},
"devDependencies": {
"@types/express": "^5.0.2",
"@types/qrcode": "^1.5.5",
"ts-node": "^10.9.2",
"tsx": "^4.20.3",
"typescript": "^5.8.3"
}
}
+40 -2
View File
@@ -9,6 +9,35 @@ import { Boom } from "@hapi/boom";
let sock: ReturnType<typeof makeWASocket>;
let latestQR: string | null = null;
let reconnecting = false;
// Last-resort safety net. An uncaught error means the process is in an
// undefined state, so we log the cause and exit; the supervisor
// (docker restart: unless-stopped) brings it back in a clean state.
// We never swallow these and keep running on corrupted state.
process.on("unhandledRejection", (reason) => {
console.error("Unhandled rejection:", reason);
process.exit(1);
});
process.on("uncaughtException", (err) => {
console.error("Uncaught exception:", err);
process.exit(1);
});
// Reconnect with the rejection handled at the source. A failed attempt must
// re-arm the loop, otherwise a single transient error leaves the bot dead.
function scheduleReconnect() {
if (reconnecting) return;
reconnecting = true;
setTimeout(() => {
startWhatsApp().catch((err) => {
console.error("Reconnect failed:", err);
reconnecting = false;
scheduleReconnect();
});
}, 1000);
}
async function startWhatsApp() {
const { state, saveCreds } = await useMultiFileAuthState("./auth");
@@ -29,10 +58,16 @@ async function startWhatsApp() {
if (connection === "close") {
const reason = (lastDisconnect?.error as Boom)?.output?.statusCode;
console.log("Connection closed:", DisconnectReason[reason]);
setTimeout(startWhatsApp, 1000);
if (reason === DisconnectReason.loggedOut) {
console.log("Session logged out — not reconnecting. Re-pair via QR to resume.");
reconnecting = false;
return;
}
scheduleReconnect();
} else if (connection === "open") {
console.log("Connected to WhatsApp");
latestQR = null;
reconnecting = false;
}
});
}
@@ -85,4 +120,7 @@ async function startServer() {
app.listen(PORT, () => console.log(`API listening on port ${PORT}`));
}
startServer().catch(console.error);
startServer().catch((err) => {
console.error("Fatal startup error:", err);
process.exit(1);
});
+2 -1
View File
@@ -26,7 +26,8 @@
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
"module": "NodeNext", /* Specify what module code is generated. Required for ESM-only Baileys 6.7.x. */
"moduleResolution": "NodeNext", /* Resolve modules the way Node.js ESM does. */
"rootDir": "src", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */