UNPKG

neroxbailx

Version:

baileys whatsapp-api

170 lines (150 loc) 6.4 kB
"use strict" Object.defineProperty(exports, "__esModule", { value: true }) /** * Session Error Handler untuk mengatasi error "No sessions" * @param {Object} options - Configuration options * @param {Function} options.logger - Logger instance * @param {Object} options.signalRepository - Signal repository instance * @param {Object} options.authState - Authentication state * @param {Function} options.assertSessions - Function to assert sessions * @param {Function} options.query - Query function * @returns {Object} Error handler functions */ function makeSessionErrorHandler({ logger, signalRepository, authState, assertSessions, query }) { /** * Handle session errors and attempt recovery * @param {Error} error - The error that occurred * @param {string} jid - The JID that caused the error * @param {Function} retryFunction - Function to retry after session recovery * @param {number} maxRetries - Maximum number of retry attempts * @returns {Promise<any>} Result of retry or throws error */ const handleSessionError = async (error, jid, retryFunction, maxRetries = 3) => { const errorMessage = error.message || error.toString() // Check if this is a session-related error if (errorMessage.includes('No sessions') || errorMessage.includes('No session') || errorMessage.includes('SessionError')) { logger.warn({ jid, error: errorMessage }, 'Session error detected, attempting recovery') try { // Force fetch new session for this JID await assertSessions([jid], true) logger.info({ jid }, 'Session recovered, retrying operation') // Retry the original operation return await retryFunction() } catch (recoveryError) { logger.error({ jid, recoveryError }, 'Failed to recover session') // If recovery fails, try to clear and recreate session try { await clearAndRecreateSession(jid) return await retryFunction() } catch (finalError) { logger.error({ jid, finalError }, 'Final session recovery attempt failed') throw new Error(`Session recovery failed for ${jid}: ${finalError.message}`) } } } // If not a session error, re-throw original error throw error } /** * Clear and recreate session for a JID * @param {string} jid - The JID to recreate session for */ const clearAndRecreateSession = async (jid) => { logger.debug({ jid }, 'Clearing and recreating session') try { // Clear existing session const signalId = signalRepository.jidToSignalProtocolAddress(jid) await authState.keys.set({ 'session': { [signalId]: null } }) // Force refetch session keys const result = await query({ tag: 'iq', attrs: { xmlns: 'encrypt', type: 'get', to: 's.whatsapp.net', }, content: [ { tag: 'key', attrs: {}, content: [{ tag: 'user', attrs: { jid }, }] } ] }) // Check if result has proper structure before processing if (!result || !result.content || !Array.isArray(result.content)) { logger.warn({ jid, result }, 'Invalid query result structure') return } // Inject new session with error handling try { const Utils_1 = require("../Utils") await Utils_1.parseAndInjectE2ESessions(result, signalRepository) logger.info({ jid }, 'Session successfully recreated') } catch (parseError) { logger.warn({ jid, parseError }, 'Failed to parse E2E sessions, but continuing') // Don't throw here - session might still work } } catch (error) { logger.error({ jid, error }, 'Failed to recreate session') throw error } } /** * Wrap a function with session error handling * @param {Function} fn - Function to wrap * @param {string} jid - JID for session context * @returns {Function} Wrapped function */ const withSessionErrorHandling = (fn, jid) => { return async (...args) => { try { return await fn(...args) } catch (error) { return await handleSessionError(error, jid, () => fn(...args)) } } } /** * Check if JID has valid session * @param {string} jid - JID to check * @returns {Promise<boolean>} True if session exists */ const hasValidSession = async (jid) => { try { const signalId = signalRepository.jidToSignalProtocolAddress(jid) const sessions = await authState.keys.get('session', [signalId]) return !!sessions[signalId] } catch (error) { logger.debug({ jid, error }, 'Error checking session validity') return false } } /** * Ensure session exists for JID * @param {string} jid - JID to ensure session for * @returns {Promise<void>} */ const ensureSession = async (jid) => { const hasSession = await hasValidSession(jid) if (!hasSession) { logger.debug({ jid }, 'Session not found, creating new session') await assertSessions([jid], true) } } return { handleSessionError, clearAndRecreateSession, withSessionErrorHandling, hasValidSession, ensureSession } } module.exports = { makeSessionErrorHandler }