fix: delete instance cleanup on baileys failure#2508
Conversation
There was a problem hiding this comment.
Sorry @antonio-abrantes, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
Hi! As part of our PR triage, we re-ran CI on this PR and the Check Code Quality workflow is failing. Could you please:
Once CI is green I'll re-review for merge. Thanks! |
|
Boa refatoração — quebrar o try/catch monolítico em steps isolados é a forma idiomática correta de cleanup robusto, e adicionar Bloqueadores para o merge:
Após os 3 itens, aprovo. |
|
Olá @antonio-abrantes, obrigado pela contribuição — o fix está correto e endereça um problema real de produção (instâncias travadas no A PR está em estado git fetch upstream
git rebase upstream/develop
git push --force-with-leaseApós o rebase, mergeio. Obrigado! |
ad917d4 to
daed3fa
Compare
|
🟢 👍 Na |
dpaes
left a comment
There was a problem hiding this comment.
Approved.
Reviewed independently against develop:
- Real bug fixed: in the original
removeInstancethetryhad only afinally(nocatch). IfsendDataWebhook(REMOVE_INSTANCE)threw (dead Baileys socket), the exception propagated and skippedcleaningUp/cleaningStoreDataand thedelete this.waInstances[instanceName], leaving a stale in-memory entry until the process restarted. Same pattern in the controller'sdeleteInstance. Isolating each step into its owntry/catchand guaranteeing the delete/emit always run is the correct fix. - The
awaits added tocleaningUp/cleaningStoreData(bothasync) are right: they were fire-and-forget, causing unhandled rejections and a race with the subsequent delete. The bodies only do idempotent cleanup (deleteMany, rmSync, cache.delete), so sequentialawaitdoesn't change success semantics — it just makes it deterministic. Deletion still proceeds even if one step fails.
Focused and additive, no regression. LGTM 👍
Non-blocking suggestions for a follow-up commit (optional, include if you want — none block this merge):
clearDelInstanceTimeis left outside a try/catch in the monitor service. It's synchronous and trivial (and it had no dedicated catch in the original either), but if it ever throws synchronously it would abort the rest of the cleanup inside the async listener — wrapping it for consistency would be tidier.sendDataWebhookin the controller'sdeleteInstancestill has noawaitinside its try/catch — if it returns a rejecting promise, the synchronous catch won't capture it. Identical to the original (not a regression), just not hardened like the other steps.error.toString()→error?.message ?? String(error): nice safety improvement (avoids a TypeError whenerroris null/undefined). Slightly tangential to the PR's theme but on the same axis (safe error stringify) and trivial, so fine to keep.
📋 Description
🐛 Problem
When calling
DELETE /instance/delete/{instanceName}on a corruptedinstance (disconnected/bugged Baileys session), the API returns:
{ "status": 400, "error": "Bad Request", "response": { "message": ["[object Object]"] } }After this error, the instance name remains permanently blocked in
waInstancesmemory. Even after manually cleaning the database, Redis,and session files, calling
POST /instance/createwith the same namereturns:
{ "status": 403, "message": ["This name \"agent-xxx\" is already in use."] }The only workaround was restarting the container — not viable in production environments.
🔍 Root Cause
Two bugs working together:
1. Aborted cleanup
deleteInstance()stopped execution iflogout()failed2. Bad error serialization
[object Object]✅ Fix
Split
try/catchinto isolated stepsEnsure cleanup always runs
Always remove instance from
waInstancesFix error serialization using:
🔗 Related Issue
Closes # (leave empty if not applicable)
🧪 Type of Change
🧪 Testing
📸 Screenshots (if applicable)
N/A
✅ Checklist
📝 Additional Notes
Tested in production environment with Docker Swarm + PostgreSQL + Redis.
Fix only affects failure path — no impact on healthy instances.
The endpoint now returns
{ status: 'SUCCESS' }even on partial failures.Logout and webhook steps were changed from "abort on error" to
logger.warn.This is intentional — the cleanup is best-effort to ensure the instance
name is always released from
waInstancesmemory, even when secondary steps fail.Clients relying on
4xxresponses to detect cleanup failures will need toadjust their logic.