Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bulk Delete Messages with index.json fails. #562

Open
4 tasks done
RyouFuchiKyou opened this issue Nov 8, 2023 · 5 comments
Open
4 tasks done

Bulk Delete Messages with index.json fails. #562

RyouFuchiKyou opened this issue Nov 8, 2023 · 5 comments

Comments

@RyouFuchiKyou
Copy link

Undiscord Version

v5.2.3

Browser

1.60.110 Chromium: 119.0.6045.105 (Official Build) (64-bit)

Extension

TamperMonkey

Reproduction steps

Uploaded index.json
Error code.

Actual results

Squat. Error code.

Error searching messages, API responded with status 403!
{"message":"Missing Access","code":50001}
CoreException {}

Expected results

Start deleting all dm's.

Bug affects

  • DMs
  • DMs (group)
  • Channels
  • Channel (NSFW)

Additional information & file uploads

image

@RyouFuchiKyou
Copy link
Author

Something is happening within the file. I had to personally edit it down to DM ID's only then paste it in by hand.

@SeraphCoding
Copy link

I did some digging.
Essentially:
The error handling in the script is quite lackluster - instead of skipping failed messages, the entire thing just crashes.

It will fail processing the index.json when the following is true:

  • The name of the chat is "null" (a lot of them)
  • The messages are on a server you do not have access to anymore (which will be a lot of them)
  • The messages are in a thread that has been archived (also access)
  • The messages are in a channel on a server that you DO have access to but the channel has been deleted/archived/changed in a way where you lost access

Those are the main causes I could identify.

@yazanzaid00
Copy link

yazanzaid00 commented Nov 30, 2023

Temporary Workaround

Due to limited time, I couldn’t thoroughly debug the issue and solve it more elegantly. It appears that undiscord doesn’t properly manage abandoned/deleted servers, channels, or messages. As a temporary solution, I’ve bypassed all errors, allowing the code to continue to the next message even if an error arises. Please be aware that this code should be used at your own risk. I didn’t review the entire undiscord code; I began troubleshooting from the recurring error message and attempted to catch the error before the program exited.

Screenshot of running undiscord bulk delete

Modifications Made

  1. I modified the runBatch function to ensure it continues to the next message even if an error is encountered:
async runBatch(queue) {
  if (this.state.running) return log.error('Already running!');

  log.info(`Runnning batch with queue of ${queue.length} jobs`);
  for (let i = 0; i < queue.length; i++) {
    const job = queue[i];
    log.info('Starting job...', `(${i + 1}/${queue.length})`);

    // set options
    this.options = {
      ...this.options, // keep current options
      ...job, // override with options for that job
    };

    try {
      await this.run(true);
    } catch (error) {
      log.error('Error in job', `(${i + 1}/${queue.length})`, error);
    }

    if (!this.state.running) break;

    log.info('Job ended.', `(${i + 1}/${queue.length})`);
    this.resetState();
    this.options.askForConfirmation = false;
    this.state.running = true; // continue running
  }

  log.info('Batch finished.');
  this.state.running = false;
}
  1. I removed the explicit throw. I also employed a try-catch block on !resp.ok to prevent exceptions from being thrown:
	    if (!resp.ok) {
	      // searching messages too fast
	      if (resp.status === 429) {
			// existing error handling code...
	      }
		  // Replace only this current else block
		  else {
			const body = await resp.text();
			try {
			  const r = JSON.parse(body);
			  if (resp.status === 400 && r.code === 50083) {
				// existing error handling code...
			  } else {
				log.error(`Error deleting message, API responded with status ${resp.status}!`, r);
				log.verb('Related object:', redact(JSON.stringify(message)));
				this.state.failCount++;
				// Instead of throwing an error, just return a failure status
				return 'FAILED';
			  }
			} catch (e) {
			  log.error(`Fail to parse JSON. API responded with status ${resp.status}!`, body);
			  // Again, instead of throwing an error, just return a failure status
			  return 'FAILED';
			}
		  }
	    }

@SeraphCoding
Copy link

Temporary Workaround

Due to limited time, I couldn’t thoroughly debug the issue and solve it more elegantly. It appears that undiscord doesn’t properly manage abandoned/deleted servers, channels, or messages. As a temporary solution, I’ve bypassed all errors, allowing the code to continue to the next message even if an error arises. Please be aware that this code should be used at your own risk. I didn’t review the entire undiscord code; I began troubleshooting from the recurring error message and attempted to catch the error before the program exited.

Screenshot of running undiscord bulk delete

Modifications Made

1. I modified the `runBatch` function to ensure it continues to the next message even if an error is encountered:
async runBatch(queue) {
  if (this.state.running) return log.error('Already running!');

  log.info(`Runnning batch with queue of ${queue.length} jobs`);
  for (let i = 0; i < queue.length; i++) {
    const job = queue[i];
    log.info('Starting job...', `(${i + 1}/${queue.length})`);

    // set options
    this.options = {
      ...this.options, // keep current options
      ...job, // override with options for that job
    };

    try {
      await this.run(true);
    } catch (error) {
      log.error('Error in job', `(${i + 1}/${queue.length})`, error);
    }

    if (!this.state.running) break;

    log.info('Job ended.', `(${i + 1}/${queue.length})`);
    this.resetState();
    this.options.askForConfirmation = false;
    this.state.running = true; // continue running
  }

  log.info('Batch finished.');
  this.state.running = false;
}
2. I removed the explicit throw. I also employed a try-catch block on !resp.ok to prevent exceptions from being thrown:
	    if (!resp.ok) {
	      // searching messages too fast
	      if (resp.status === 429) {
			// existing error handling code...
	      }
		  // Replace only this current else block
		  else {
			const body = await resp.text();
			try {
			  const r = JSON.parse(body);
			  if (resp.status === 400 && r.code === 50083) {
				// existing error handling code...
			  } else {
				log.error(`Error deleting message, API responded with status ${resp.status}!`, r);
				log.verb('Related object:', redact(JSON.stringify(message)));
				this.state.failCount++;
				// Instead of throwing an error, just return a failure status
				return 'FAILED';
			  }
			} catch (e) {
			  log.error(`Fail to parse JSON. API responded with status ${resp.status}!`, body);
			  // Again, instead of throwing an error, just return a failure status
			  return 'FAILED';
			}
		  }
	    }

Did something similar to cope with the failures and just skip them. In all honesty, explicit error handling for these messages is only beneficial for logging purposes in the first place, so the user "knows" that there are some unreachable messages.

So just skipping and continuing is the way to go.

@vanwarcho
Copy link

@yazanzaid00 Can you send the full modified code since this isnt working for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants