Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "unoapi-cloud",
"version": "2.8.0",
"version": "2.8.1-alpha",
"description": "Unoapi Cloud",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
5 changes: 3 additions & 2 deletions src/services/auto_connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ export const autoConnect = async (
try {
const store = await config.getStore(phone, config)
const { sessionStore } = store
if ((await sessionStore.isStatusConnecting(phone)) || (await sessionStore.isStatusOnline(phone))) {
logger.info(`Update session status to auto connect ${phone}...`)
const currentStatus = await sessionStore.getStatus(phone)
if (['connecting', 'online', 'reloading'].includes(currentStatus)) {
logger.info(`Update session current status ${currentStatus} to offline in session ${phone}...`)
await sessionStore.setStatus(phone, 'offline')
}
getClient({ phone, listener, getConfig, onNewLogin })
Expand Down
12 changes: 9 additions & 3 deletions src/services/reload_baileys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,21 @@ export class ReloadBaileys extends Reload {
logger.debug('Reload broker for phone %s', phone)
return super.run(phone)
}
const store = await config.getStore(phone, config)
const { sessionStore } = store
const currentStatus = await sessionStore.getStatus(phone)
if (currentStatus == 'reloading') {
logger.info('Already reloading session %s!', phone)
return
}
await sessionStore.setStatus(phone, 'reloading')
Comment on lines +30 to +37
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Status stuck at 'reloading' if run() throws after line 37.

If any operation after setStatus(phone, 'reloading') throws (e.g., getClient, disconnect, super.run), the status is never reset and all future reloads for this phone will be permanently blocked by the early-return guard on line 33. Wrap the reload body in a try/finally to ensure the status is cleared on failure.

Proposed fix
     await sessionStore.setStatus(phone, 'reloading')
+    try {
     const currentClient = await this.getClient({
       phone,
       listener: this.listener,
       getConfig: this.getConfig,
       onNewLogin: this.onNewLogin,
     })
     if (['online', 'standby', 'connecting'].includes(currentStatus)) {
       logger.warn('Reload disconnect session %s!', phone)
       await currentClient?.disconnect()
     }
     await super.run(phone)
     await sessionStore.setStatus(phone, 'online') // to clear standby
     await sessionStore.setStatus(phone, 'disconnected')
     await this.getClient({
       phone,
       listener: this.listener,
       getConfig: this.getConfig,
       onNewLogin: this.onNewLogin,
     })
     logger.info('Reloaded session %s!', phone)
+    } catch (e) {
+      logger.error(e, 'Error reloading session %s', phone)
+      await sessionStore.setStatus(phone, 'offline')
+      throw e
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const store = await config.getStore(phone, config)
const { sessionStore } = store
const currentStatus = await sessionStore.getStatus(phone)
if (currentStatus == 'reloading') {
logger.info('Already reloading session %s!', phone)
return
}
await sessionStore.setStatus(phone, 'reloading')
const store = await config.getStore(phone, config)
const { sessionStore } = store
const currentStatus = await sessionStore.getStatus(phone)
if (currentStatus == 'reloading') {
logger.info('Already reloading session %s!', phone)
return
}
await sessionStore.setStatus(phone, 'reloading')
try {
const currentClient = await this.getClient({
phone,
listener: this.listener,
getConfig: this.getConfig,
onNewLogin: this.onNewLogin,
})
if (['online', 'standby', 'connecting'].includes(currentStatus)) {
logger.warn('Reload disconnect session %s!', phone)
await currentClient?.disconnect()
}
await super.run(phone)
await sessionStore.setStatus(phone, 'online') // to clear standby
await sessionStore.setStatus(phone, 'disconnected')
await this.getClient({
phone,
listener: this.listener,
getConfig: this.getConfig,
onNewLogin: this.onNewLogin,
})
logger.info('Reloaded session %s!', phone)
} catch (e) {
logger.error(e, 'Error reloading session %s', phone)
await sessionStore.setStatus(phone, 'offline')
throw e
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/services/reload_baileys.ts` around lines 30 - 37, The reload flow
currently sets sessionStore.setStatus(phone, 'reloading') then proceeds and may
throw, leaving the status stuck; update the logic in the reload function (the
block that calls config.getStore, sessionStore.getStatus, sessionStore.setStatus
and then calls getClient, disconnect, super.run) to wrap the remainder of the
reload body in a try/finally so that sessionStore.setStatus(phone,
<previousStatus or null/''>) is always called in the finally block to
clear/reset the status even if getClient, disconnect, super.run (or any other
operation) throws; preserve retrieval of the prior status from
sessionStore.getStatus(phone) before setting 'reloading' and restore that value
(or a cleared state) in the finally.

const currentClient = await this.getClient({
phone,
listener: this.listener,
getConfig: this.getConfig,
onNewLogin: this.onNewLogin,
})
const store = await config.getStore(phone, config)
const { sessionStore } = store
if ((await sessionStore.isStatusOnline(phone)) || (await sessionStore.isStatusStandBy(phone)) || (await sessionStore.isStatusConnecting(phone))) {
if (['online', 'standby', 'connecting'].includes(currentStatus)) {
logger.warn('Reload disconnect session %s!', phone)
await currentClient?.disconnect()
}
Expand Down
6 changes: 5 additions & 1 deletion src/services/session_store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MAX_CONNECT_RETRY } from '../defaults'
import logger from './logger'

export type sessionStatus = 'offline' | 'online' | 'disconnected' | 'connecting' | 'standby' | 'restart_required'
export type sessionStatus = 'offline' | 'online' | 'disconnected' | 'connecting' | 'standby' | 'restart_required' | 'reloading'

const statuses: Map<string, string> = new Map<string, string>()
const retries: Map<string, number> = new Map<string, number>()
Expand All @@ -23,6 +23,10 @@ export abstract class SessionStore {
return (await this.getStatus(phone)) == 'online'
}

async isStatusReloading(phone: string) {
return (await this.getStatus(phone)) == 'reloading'
}

async isStatusConnecting(phone: string) {
return (await this.getStatus(phone)) == 'connecting'
}
Expand Down
2 changes: 1 addition & 1 deletion src/services/session_store_redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class SessionStoreRedis extends SessionStore {

async setStatus(phone: string, status: sessionStatus) {
logger.info(`Session status ${phone} change from ${await this.getStatus(phone)} to ${status}`)
if (['online', 'restart_required'].includes(status)) {
if (['online', 'restart_required', 'reloading'].includes(status)) {
await this.clearConnectCount(phone)
}
return setSessionStatus(phone, status)
Expand Down
Loading