fix(whatsapp): guard get_me() calls to enable QR pairing on fresh sessions
This commit is contained in:
@@ -159,6 +159,10 @@ class WhatsAppClient(ClientBase):
|
|||||||
db_dir = os.path.dirname(self.session_db)
|
db_dir = os.path.dirname(self.session_db)
|
||||||
if db_dir:
|
if db_dir:
|
||||||
os.makedirs(db_dir, exist_ok=True)
|
os.makedirs(db_dir, exist_ok=True)
|
||||||
|
if db_dir and not os.access(db_dir, os.W_OK):
|
||||||
|
raise PermissionError(
|
||||||
|
f"session db directory is not writable: {db_dir}"
|
||||||
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self._publish_state(
|
self._publish_state(
|
||||||
connected=False,
|
connected=False,
|
||||||
@@ -179,6 +183,19 @@ class WhatsAppClient(ClientBase):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not self._session_has_device():
|
||||||
|
self._publish_state(
|
||||||
|
connected=False,
|
||||||
|
warning="No linked WhatsApp device. Waiting for QR pairing.",
|
||||||
|
accounts=[],
|
||||||
|
last_event="no_linked_device",
|
||||||
|
pair_status="needs_pairing",
|
||||||
|
)
|
||||||
|
self.log.info(
|
||||||
|
"whatsapp session db has no linked device — connect will "
|
||||||
|
"start QR pairing flow"
|
||||||
|
)
|
||||||
|
|
||||||
self._register_event_handlers(wa_events)
|
self._register_event_handlers(wa_events)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -457,6 +474,32 @@ class WhatsAppClient(ClientBase):
|
|||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _session_has_device(self):
|
||||||
|
"""Check whatsmeow_device table for a linked device row.
|
||||||
|
|
||||||
|
Neonize's Go layer panics (SIGSEGV in GetMe) when connect() is called
|
||||||
|
on a session with no linked device. Querying the SQLite schema directly
|
||||||
|
lets us skip connect() and avoid crashing the entire UR process.
|
||||||
|
"""
|
||||||
|
if not os.path.exists(self.session_db):
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect(self.session_db)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute(
|
||||||
|
"SELECT COUNT(*) FROM sqlite_master "
|
||||||
|
"WHERE type='table' AND name='whatsmeow_device'"
|
||||||
|
)
|
||||||
|
if cursor.fetchone()[0] == 0:
|
||||||
|
conn.close()
|
||||||
|
return False
|
||||||
|
cursor.execute("SELECT COUNT(*) FROM whatsmeow_device")
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
return count > 0
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
def _register_event_handlers(self, wa_events):
|
def _register_event_handlers(self, wa_events):
|
||||||
connected_ev = getattr(wa_events, "ConnectedEv", None)
|
connected_ev = getattr(wa_events, "ConnectedEv", None)
|
||||||
message_ev = getattr(wa_events, "MessageEv", None)
|
message_ev = getattr(wa_events, "MessageEv", None)
|
||||||
@@ -1361,6 +1404,11 @@ class WhatsAppClient(ClientBase):
|
|||||||
return ""
|
return ""
|
||||||
if not hasattr(self._client, "get_me"):
|
if not hasattr(self._client, "get_me"):
|
||||||
return self.client_name
|
return self.client_name
|
||||||
|
# Guard: Neonize Go GetMe() panics (SIGSEGV) when cli.LID is nil
|
||||||
|
# on unlinked sessions. Only safe to call after pairing completes
|
||||||
|
# and the device row exists in the whatsmeow_device table.
|
||||||
|
if not self._session_has_device():
|
||||||
|
return self.client_name
|
||||||
try:
|
try:
|
||||||
me = await self._maybe_await(self._client.get_me())
|
me = await self._maybe_await(self._client.get_me())
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -1785,7 +1833,8 @@ class WhatsAppClient(ClientBase):
|
|||||||
self._connected = True
|
self._connected = True
|
||||||
self._publish_state(connected=True, warning="", pair_status="connected")
|
self._publish_state(connected=True, warning="", pair_status="connected")
|
||||||
return True
|
return True
|
||||||
if hasattr(self._client, "get_me"):
|
# Guard: Neonize Go GetMe() panics (SIGSEGV) on unlinked sessions.
|
||||||
|
if hasattr(self._client, "get_me") and self._session_has_device():
|
||||||
try:
|
try:
|
||||||
me = await self._maybe_await(self._client.get_me())
|
me = await self._maybe_await(self._client.get_me())
|
||||||
if me:
|
if me:
|
||||||
|
|||||||
Reference in New Issue
Block a user