fix(session): return 502 when the WhatsApp unlink is not confirmed - #997
Merged
Conversation
Both engine adapters caught their own logout failure and resolved, so POST /sessions/:id/logout returned 200 and wrote a SESSION_LOGGED_OUT audit row even when the unlink never reached WhatsApp. The engines also failed differently: whatsapp-web.js kept the credentials and stayed linked, while Baileys wiped the local auth dir but stayed linked — leaving a Linked Devices entry with no local way to clear it. Adapters now rethrow after their local fallback teardown, and Baileys keeps the on-disk credentials on a failed unlink so the operator can retry. session.service.logout() uses teardownEngineSafely's return value: the session is still torn down locally (map reconciled, status updated), but an unconfirmed unlink throws BadGatewayException, so no audit row is written for an unlink that never happened. Closes #993
rmyndharis
added a commit
that referenced
this pull request
Jul 29, 2026
…the deadline race (#1001) PR #999 added two teardown-resilience tests that drive logout() with a promise hung past the 10s deadline, then await the call assuming it resolves. PR #997 (which landed first) made logout() throw BadGatewayException whenever the unlink is unconfirmed — exactly the outcome of a lost deadline race — so both tests have failed on main since #999 merged on top of it. The production behaviour from #997 is correct and already asserted explicitly (logout() rejects with 502 when the unlink is unconfirmed, but the local teardown still completes). This updates the two #999 tests to expect that rejection, while preserving what they actually exercise: the losing promise stays registered in pendingTeardowns and start() still waits for it (bounded) before re-creating the profile.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #993 (found reviewing #984). Both engine adapters caught their own
logout()failure and resolved, soPOST /sessions/:id/logoutreturned 200 and wrote aSESSION_LOGGED_OUTaudit row even when the unlink never reached WhatsApp — and the engines failed differently: whatsapp-web.js kept the credentials and stayed linked, while Baileys wiped the local auth dir but stayed linked, leaving a Linked Devices entry with no local way to clear it.destroy()fallback (the session must still die locally), the original error is rethrown so the caller learns the unlink was not confirmed.sock.logout()the socket is ended and the error rethrown, butclearAuthState()no longer runs: the stored credentials survive so the operator can start the session and retry the unlink without a QR scan.teardownEngineSafely's return value: the session is still torn down locally (engine map reconciled, status set todisconnected), but an unconfirmed unlink throwsBadGatewayException, so noSESSION_LOGGED_OUTaudit row is written for an unlink that never happened.openapi.json,docs/06, and the CHANGELOG entry are updated (the endpoint is still unreleased, so this refines the feat(session): expose POST /sessions/:id/logout to unlink the device #984 contract before it ships rather than changing a published one).Type of Change
Checklist
Related Issues
Closes #993