WhiskeySockets / Baileys

Lightweight full-featured typescript/javascript WhatsApp Web API
https://baileys.whiskeysockets.io/
MIT License
3.17k stars 1.1k forks source link

[BUG] creds.json broke after some reconnections. #794

Closed ElielsonU closed 1 month ago

ElielsonU commented 2 months ago

Describe the bug Actually, i've been ignoring status codes diferent than 401 and reconecting the session. But after some reconnections the creds.json broke and the session is lost. But funny, when you fix the json the connection normalize again.

To Reproduce Steps to reproduce the behavior:

  1. Created a new connection
  2. Reconnect the session ignoring status codes diferent than 401

Expected behavior It was expected to maintan the session running.

Environment (please complete the following information):

image

jonhy751 commented 2 months ago

+1

luis-luciqm commented 2 months ago

+1

caioRafael commented 2 months ago

+1

FabioRocha462 commented 2 months ago

help me

Mirlaaa commented 2 months ago

👍🏽 Upvote! This issue deserves attention.

Alien-Alfa commented 2 months ago

Good one! this is a serious issue. I had to make adjustments in my code to fix this like: when creds.json break it will show qr so if(s.qr) Delete the current session; pull the session from the saved server; restart. This is automated but the root of the problem is not fixed

MaznAbdullah commented 2 months ago

up+

ElielsonU commented 2 months ago

Good one! this is a serious issue. I had to make adjustments in my code to fix this like: when creds.json break it will show qr so if(s.qr) Delete the current session; pull the session from the saved server; restart. This is automated but the root of the problem is not fixed

Nice! After all, i've tested some ways to fix this. And you can fix the broken json by erasing all the characters after the penutimate brace. With the json fixed, you can just reconnect and all will work fine. You don't need to read the qr_code again.

SheIITear commented 2 months ago

Good one! this is a serious issue. I had to make adjustments in my code to fix this like: when creds.json break it will show qr so if(s.qr) Delete the current session; pull the session from the saved server; restart. This is automated but the root of the problem is not fixed

Nice! After all, i've tested some ways to fix this. And you can fix the broken json by erasing all the characters after the penutimate brace. With the json fixed, you can just reconnect and all will work fine. You don't need to read the qr_code again.

This won't always fix broken json as there might still be missing closing brackets and such so I wouldn't rely on that. Are you guys closing the whole process using something like sigkill or just normally having it reconnect during disconnects?

ElielsonU commented 2 months ago

Good one! this is a serious issue. I had to make adjustments in my code to fix this like: when creds.json break it will show qr so if(s.qr) Delete the current session; pull the session from the saved server; restart. This is automated but the root of the problem is not fixed

Nice! After all, i've tested some ways to fix this. And you can fix the broken json by erasing all the characters after the penutimate brace. With the json fixed, you can just reconnect and all will work fine. You don't need to read the qr_code again.

This won't always fix broken json as there might still be missing closing brackets and such so I wouldn't rely on that. Are you guys closing the whole process using something like sigkill or just normally having it reconnect during disconnects?

It occurs in both cases. After a few times making a new connection ignoring the another error statuses or just killing the process with ctrl+c.

SheIITear commented 2 months ago

Good one! this is a serious issue. I had to make adjustments in my code to fix this like: when creds.json break it will show qr so if(s.qr) Delete the current session; pull the session from the saved server; restart. This is automated but the root of the problem is not fixed

Nice! After all, i've tested some ways to fix this. And you can fix the broken json by erasing all the characters after the penutimate brace. With the json fixed, you can just reconnect and all will work fine. You don't need to read the qr_code again.

This won't always fix broken json as there might still be missing closing brackets and such so I wouldn't rely on that. Are you guys closing the whole process using something like sigkill or just normally having it reconnect during disconnects?

It occurs in both cases. After a few times making a new connection ignoring the another error statuses or just killing the process with ctrl+c.

Force killing a process is not a good idea, you most likely have killed the process when it was still writing the file.

KazeDevID commented 1 month ago

help me🙂

Im-Dims commented 1 month ago

Nice

iqstore78 commented 1 month ago

😯

davidlg commented 1 month ago

Same here!!!!

Salientekill commented 1 month ago

Up +1

raphaelvserafim commented 1 month ago

up Same here

raphaelvserafim commented 1 month ago

My solution for now is this

export async function fixJSON(filePath: string) { const jsonString = await fsPromises.readFile(filePath, "utf8"); try { return JSON.parse(jsonString); } catch (error) { if (error instanceof SyntaxError) { try { var fixedString = jsonString.replace(/}"(lastPropHash)/g, ',"$1'); await fsPromises.writeFile(filePath, fixedString, "utf8"); } catch (innerError) { return true; } } else { return true; } } }

Alien-Alfa commented 1 month ago

Good one! this is a serious issue. I had to make adjustments in my code to fix this like: when creds.json break it will show qr so if(s.qr) Delete the current session; pull the session from the saved server; restart. This is automated but the root of the problem is not fixed

Nice! After all, i've tested some ways to fix this. And you can fix the broken json by erasing all the characters after the penutimate brace. With the json fixed, you can just reconnect and all will work fine. You don't need to read the qr_code again.

Actually my creds.json is saved in the cloud so when the creds in bot breaks it will show the qr if that happens my function will replace the creds with the working file from cloud.

or you can just save a backup creds.json file in the bot itselff and do as I did if(error) replace the session/creds.json with backup/creds.json

punitagarwal4 commented 1 month ago

My solution for now is this

export async function fixJSON(filePath: string) { const jsonString = await fsPromises.readFile(filePath, "utf8"); try { return JSON.parse(jsonString); } catch (error) { if (error instanceof SyntaxError) { try { var fixedString = jsonString.replace(/}"(lastPropHash)/g, ',"$1'); await fsPromises.writeFile(filePath, fixedString, "utf8"); } catch (innerError) { return true; } } else { return true; } } }

So when do we exactly need to call this function, when the connection state is "open" ?

raphaelvserafim commented 1 month ago

My solution for now is this export async function fixJSON(filePath: string) { const jsonString = await fsPromises.readFile(filePath, "utf8"); try { return JSON.parse(jsonString); } catch (error) { if (error instanceof SyntaxError) { try { var fixedString = jsonString.replace(/}"(lastPropHash)/g, ',"$1'); await fsPromises.writeFile(filePath, fixedString, "utf8"); } catch (innerError) { return true; } } else { return true; } } }

So when do we exactly need to call this function, when the connection state is "open" ?

I have a loop that keeps checking every 6 seconds, verifying the file, because there are no events.

punitagarwal4 commented 1 month ago

My solution for now is this export async function fixJSON(filePath: string) { const jsonString = await fsPromises.readFile(filePath, "utf8"); try { return JSON.parse(jsonString); } catch (error) { if (error instanceof SyntaxError) { try { var fixedString = jsonString.replace(/}"(lastPropHash)/g, ',"$1'); await fsPromises.writeFile(filePath, fixedString, "utf8"); } catch (innerError) { return true; } } else { return true; } } }

So when do we exactly need to call this function, when the connection state is "open" ?

I have a loop that keeps checking every 6 seconds, verifying the file, because there are no events.

Didn't work

lucianodltec commented 1 month ago

+1

allanlisboa commented 1 month ago

+1

allburov commented 1 month ago

Also experiencing the issue

a.replace(/}"(lastPropHash)/g, ',"$1')

that one helped UPD - not always tho, because the last key can be different one, had to write "safe json loader" with stack to keep the right order for {}

allburov commented 1 month ago

you most likely have killed the process when it was still writing the file.

@SheIITear or it's because fs/promises.writeFile has been used - see the similar issue in nodejs https://github.com/nodejs/node/issues/26338

The file system (and nodejs) doesn't care about concurrent writes, and because on creds.update event we usually just call saveCreds (as in the example https://github.com/WhiskeySockets/Baileys/blob/master/Example/example.ts#L215-L217) it causes race condition issues.

I'll look at useMultiFileAuthState so we can add some Concurrent(saveCreds) wrapper or even smthg like Debounce(saveCreds) alternative

Salientekill commented 1 month ago

you most likely have killed the process when it was still writing the file.

@SheIITear or it's because fs/promises.writeFile has been used - see the similar issue in nodejs nodejs/node#26338

The file system (and nodejs) doesn't care about concurrent writes, and because on creds.update event we usually just call saveCreds (as in the example https://github.com/WhiskeySockets/Baileys/blob/master/Example/example.ts#L215-L217) it causes race condition issues.

I'll look at useMultiFileAuthState so we can add some Concurrent(saveCreds) wrapper or even smthg like Debounce(saveCreds) alternative

If you can, it will help a lot, I'm not using the latest versions precisely because of this problem, I'm using 6.6.1

allburov commented 1 month ago

Here you're! @SheIITear have a look when you have time :pray: https://github.com/WhiskeySockets/Baileys/pull/824

natanjborba commented 1 month ago

Here you're! @SheIITear have a look when you have time 🙏 #824

Here I was having this problem and testing your PR solved the problem, thank you!

Salientekill commented 1 month ago

The disconnect problem started after this change: https://github.com/WhiskeySockets/Baileys/commit/fbbb511fb8464ea744e2abc416c8cef54c0e317c

PurpShell commented 1 month ago

keepAliveIntervalMs: 999999,

PurpShell commented 1 month ago

How about we buffer this event?

azudindaem commented 1 month ago

How about we buffer this event?

event better.. it might affect memory, but it will prevent the JSON from breaking

allburov commented 1 month ago

How about we buffer this event?

Make sense, it'll help in the file storage and any remote storages to reduce number of creds.update events!

I've checked the creds.update events we emit right now and not 100% sure how to buffer it right in a single place... as a quick fix just for "file auth storage" I think we could live with locks forawhile, just to fix the issue asap - https://github.com/WhiskeySockets/Baileys/pull/824 The node-cache manager that works with files (https://github.com/rolandstarke/node-cache-manager-fs-hash) also has lock mechanism. It doesn't affect the rest of the code, so later when we add event buffering (I'll check that) it'll work together. WDYT @PurpShell ?

allburov commented 1 month ago

The fix is available in the latest github version (not in npm yet). Remember to use provided useMultiFileAuthState, if you're using your custom auth file store - update won't help!