Added emptyPageRetries#729
Open
idkSpisek wants to merge 1 commit intovictornpb:masterfrom
Open
Conversation
ayubun
approved these changes
Nov 11, 2025
ayubun
left a comment
There was a problem hiding this comment.
i love this idea ! i also face sporadic empty page issues and having a retry count of 2 sounds much more resilient.
for what it's worth, i noticed search delays of less than 30s seem to cause this to occur more consistently :o
ayubun
reviewed
Nov 11, 2025
Comment on lines
+182
to
+187
| if (this.state.emptyPageRetryCount >= this.options.emptyPageRetries) { | ||
| log.verb('Ended because API returned empty pages after maximum retries.'); | ||
| log.verb('[End state]', this.state); | ||
| if (isJob) break; // break without stopping if this is part of a job | ||
| this.state.running = false; | ||
| } else { |
There was a problem hiding this comment.
for what it's worth, if the retry count is 1 (which would imply it will retry at least once(?)), this will exit without retrying
perhaps a > instead of >= would fit the naming better ? or, renaming emptyPageRetries to maxEmptyPagesBeforeExiting or something similar would work with >=, where a value of 1 implies no need for a retry
TheCellMaster
added a commit
to TheCellMaster/undiscord
that referenced
this pull request
Apr 15, 2026
Major refactor: modular architecture + upstream PR features + security fixes. === ARCHITECTURE (complete rewrite) === - Split monolithic undiscord-core.js (584 lines) into 5 focused modules: - src/core/undiscord-core.js: Orchestrator (run, runBatch, stop, confirm) - src/core/search.js: Search with iterative retry (202/429 handling) - src/core/filter.js: Pure message filtering (types, pinned, bots, threads, regex) - src/core/delete.js: Delete with retry loop + rate limit adaptation - src/core/unarchive.js: Thread unarchive before delete - Split monolithic undiscord-ui.js (378 lines) into 4 modules: - src/ui/init.js: DOM mount, CSS injection, toolbar button + MutationObserver - src/ui/handlers.js: All event handlers (start, stop, getChannel, pick, etc) - src/ui/progress.js: onStart/onProgress/onStop callbacks - src/ui/logger.js: XSS-safe log rendering with ring buffer - Created src/api/discord-api.js: Pure fetch layer with AbortSignal.timeout(30s) - Split helpers.js (8 functions in 8 lines) into semantic modules: - src/utils/time.js: wait(), msToHMS() - src/utils/html.js: escapeHTML(), redact(), replaceInterpolations() - src/utils/discord.js: queryString(), ask(), toSnowflake() - Merged createElm.js + insertCss.js into src/utils/dom.js - Split CSS (theme.css 355 lines + main.css 172 lines) into 6 modules: - layout.css, components.css, scrollbar.css, redact.css, log.css, drag.css - Moved HTML templates to src/ui/html/ - Renamed utils to kebab-case (getIds -> get-ids, messagePicker -> message-picker) - Removed 12 legacy files replaced by modular architecture - Created src/utils/constants.js with shared constants === NEW FEATURES (from upstream PRs) === - victornpb#741: Poll messages (type 46) can now be deleted - victornpb#741: Bot slash command responses (type 20) excluded from deletion - victornpb#742: HTTP 403 on delete returns FAIL_SKIP instead of infinite retry loop - victornpb#743: Retry logic refactored: FAILED/FAIL_SKIP properly handled, failCount centralized - victornpb#740: HTTP 403 on search gracefully skips channel instead of canceling batch - victornpb#739: 30s delay between batch jobs to prevent API spam - victornpb#737: Thread unarchiving: attempts PATCH to unarchive before skipping - victornpb#729: Empty page retries (configurable, default 2) before stopping - victornpb#629: "Include bot/application messages" checkbox in Filter section - victornpb#610: Thread auto-detection via API when clicking "current" channel button - victornpb#603: Graceful handling of API errors 50024 (channel not found) and 50001 (missing access) - victornpb#643: Date filter warning: "Make sure you enter both date AND time" - victornpb#527/victornpb#519: Rate limit delay adds on top (never decreases) with caps === SECURITY FIXES === - S1 XSS fix: printLog now escapes all external data via escapeHTML(), preserving <x> redact tags via split pattern for streamer mode - escapeHTML() now also escapes > character - Log type validated against whitelist before becoming CSS class name - AbortSignal.timeout(30s) on ALL fetch calls (search, delete, unarchive, getChannel) replacing leaky setTimeout-based AbortController - retry_after clamped with Math.max(w, 0) to prevent negative values causing tight loops === BUG FIXES === - Fixed onStop called twice (stop() + end of run()) via guard check - Fixed missing return DELETE_RESULT.FAILED in JSON.parse catch path - Fixed filterResponse was async unnecessarily (now sync) - Fixed _searchResponse null crash with guard in filterResponse - Fixed .filter(Boolean) after map().find() to prevent undefined entries - Fixed replaceInterpolations treating falsy values (0, false, "") as missing (|| -> ??) === QUALITY IMPROVEMENTS === - DELETE_RESULT enum (Object.freeze) replaces magic strings - DELETABLE_MSG_TYPES Set replaces compound conditional - Set-based lookup for skipped messages (O(n) vs O(n^2)) - search() converted from recursive to iterative with MAX_SEARCH_RETRIES=20 - searchDelay capped at MAX_SEARCH_DELAY_MS (60s) - deleteDelay capped at MAX_DELETE_DELAY_MS (30s) - Log ring buffer: MAX_LOG_ENTRIES=5000 prevents unbounded DOM growth - Confirm preview limited to 10 messages - messagePicker timeout (30s) with automatic cleanup - drag.css selectors scoped with #undiscord - .resize-handle scoped with #undiscord - Orphan .logarea CSS class removed - MutationObserver throttle extracted to OBSERVER_THROTTLE_MS constant - All CSS variables use fallback pattern var(--new, var(--old)) - JSDoc on all public methods === BUILD === - metadata.mjs supports contributors array from package.json - @author now shows both victornpb and TheCellMaster - CLAUDE.md created with project documentation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 15, 2026
This was referenced May 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I added a setting in advanced options which allows you to specify how many times you'd like to retry deleting messages, after receiving the response from the API that "API returned an empty page".
Thought I'd be a good idea after I kept receiving that API response, cancelling my deletion process when all it took is to press the 'start delete' button again. Now I don't have to continuously check if my deletion process was cancelled, and I can leave it be, knowing that it will automatically try again if I receive that message.