Skip to content

Correctly handles redirects#92

Open
cicalese wants to merge 2 commits intomasterfrom
fix-redirect
Open

Correctly handles redirects#92
cicalese wants to merge 2 commits intomasterfrom
fix-redirect

Conversation

@cicalese
Copy link
Collaborator

@cicalese cicalese commented Feb 25, 2026

Fixes #90
Fixes #58

Summary by CodeRabbit

  • Bug Fixes
    • Redirected pages now resolve and display the target page title instead of the source title.
    • Pages are now explicitly tracked as redirects where applicable, improving categorization and UI accuracy.
    • Outgoing links now explicitly mark non-redirects, tightening link metadata for more reliable display and navigation.

@coderabbitai
Copy link

coderabbitai bot commented Feb 25, 2026

📝 Walkthrough

Walkthrough

Adds explicit redirect handling by building a redirect map from API responses and using it to resolve redirect targets and mark redirect pages; also marks outgoing link entries as non-redirects when building the page map.

Changes

Cohort / File(s) Summary
Redirect handling & page processing
resources/js/ApiPageConnectionRepo.js
Introduces _buildRedirectMap(pageInfoResponse); computes redirectMap early in _apiResponseToPagesAndLinks; uses map to resolve page.displayTitle (fallback to original title) and sets page.isRedirect = true for redirected pages.
Outgoing link page entries
resources/js/ApiConnectionsBuilder.js
When building page map for centralPage.outgoingLinks, adds isRedirect: false to stored outgoing link page objects.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Correctly handles redirects' accurately summarizes the main change: adding proper redirect handling in the codebase by building redirect maps and using them to resolve display titles.
Linked Issues check ✅ Passed The changes address both linked issues: Issue #58 is solved by introducing redirect map handling in ApiPageConnectionRepo to prevent visualization breakage, and Issue #90 is addressed by ensuring proper page entry structure with explicit isRedirect marking.
Out of Scope Changes check ✅ Passed All changes are directly related to redirect handling: modifications in ApiConnectionsBuilder ensure proper page object structure, and ApiPageConnectionRepo additions implement redirect resolution logic needed to fix the issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-redirect

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
resources/js/ApiPageConnectionRepo.js (1)

73-77: ⚠️ Potential issue | 🟡 Minor

Title icon lookup misses for redirected pages

titleIcons.images / titleIcons.text are keyed by resolved titles (built from pageInfoResponse.query.pages in _getTitleIcons), but the lookup here uses page.title, which is still the redirect-source title for outgoing-link pages (e.g. "Maps for MediaWiki" while the icon is stored under "Maps"). The icon will silently be absent for any redirected page.

Apply the same redirectMap resolution used for displayTitle:

🔧 Proposed fix
-								if (titleIcons.images[page.title]) {
-									page.image = titleIcons.images[page.title];
-								} else if (titleIcons.text[page.title]) {
-									page.text = titleIcons.text[page.title];
+								let iconKey = redirectMap[page.title] || page.title;
+								if (titleIcons.images[iconKey]) {
+									page.image = titleIcons.images[iconKey];
+								} else if (titleIcons.text[iconKey]) {
+									page.text = titleIcons.text[iconKey];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/js/ApiPageConnectionRepo.js` around lines 73 - 77, The title icon
lookup uses the original redirect-source title (page.title) so icons keyed by
resolved titles are missed; change the lookup in the block that sets
page.image/page.text to first resolve the title via the same redirectMap used
for displayTitle (e.g. let resolved = redirectMap[page.title] || page.title) and
then check titleIcons.images[resolved] and titleIcons.text[resolved] instead of
titleIcons.*[page.title], ensuring redirected pages find their icons; reference
the redirectMap, displayTitle logic and _getTitleIcons/titleIcons when making
this change.
🧹 Nitpick comments (2)
resources/js/ApiPageConnectionRepo.js (1)

28-28: Pre-existing: concat result is discarded — _addedPages never grows

Array.prototype.concat is non-mutating, so this._addedPages stays [] after every call, making the deduplication filter on line 23 permanently a no-op. Every addConnections call re-fetches all pages.

🔧 Proposed fix
-				this._addedPages.concat(pagesToAdd);
+				this._addedPages = this._addedPages.concat(pagesToAdd);

or equivalently:

-				this._addedPages.concat(pagesToAdd);
+				this._addedPages.push(...pagesToAdd);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/js/ApiPageConnectionRepo.js` at line 28, The concat call on
this._addedPages is non-mutating so this._addedPages never updates; update
addConnections to either assign the concat result back to this._addedPages
(this._addedPages = this._addedPages.concat(pagesToAdd)) or push the new items
into the array (this._addedPages.push(...pagesToAdd)) so the deduplication using
_addedPages actually works; locate the concat call and replace it with one of
these two approaches in the ApiPageConnectionRepo class so subsequent calls skip
already-added pages.
resources/js/ApiConnectionsBuilder.js (1)

60-78: Pre-existing: external link entries omit isRedirect, yielding undefined in _buildPageList

All three code paths here produce page objects without an isRedirect field. _buildPageList (line 39) copies page.isRedirect unconditionally, so external pages end up with isRedirect: undefined rather than false. Not a functional problem (external pages are skipped in ApiPageConnectionRepo display-title logic via the isExternal check), but worth aligning for consistency.

🔧 Proposed fix
-					pages[titleStr] = { title: titleStr, external: false }
+					pages[titleStr] = { title: titleStr, external: false, isRedirect: false }
 				} else {
-					pages[page['*']] = { title: page['*'], external: true }
+					pages[page['*']] = { title: page['*'], external: true, isRedirect: false }
 				}
 			} else {
-				pages[page['*']] = { title: page['*'], external: true }
+				pages[page['*']] = { title: page['*'], external: true, isRedirect: false }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/js/ApiConnectionsBuilder.js` around lines 60 - 78, The
externalLinks loop in centralPage.externalLinks.forEach assigns page objects
without an isRedirect field so _buildPageList ends up copying undefined; update
every pages[...] assignment inside that loop (both the branch where
mw.Title.newFromText succeeds and the two external branches) to include
isRedirect: false (e.g., pages[titleStr] = { title: titleStr, external: false,
isRedirect: false } and pages[page['*']] = { title: page['*'], external: true,
isRedirect: false }) so external entries consistently have isRedirect set.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@resources/js/ApiPageConnectionRepo.js`:
- Around line 73-77: The title icon lookup uses the original redirect-source
title (page.title) so icons keyed by resolved titles are missed; change the
lookup in the block that sets page.image/page.text to first resolve the title
via the same redirectMap used for displayTitle (e.g. let resolved =
redirectMap[page.title] || page.title) and then check
titleIcons.images[resolved] and titleIcons.text[resolved] instead of
titleIcons.*[page.title], ensuring redirected pages find their icons; reference
the redirectMap, displayTitle logic and _getTitleIcons/titleIcons when making
this change.

---

Nitpick comments:
In `@resources/js/ApiConnectionsBuilder.js`:
- Around line 60-78: The externalLinks loop in centralPage.externalLinks.forEach
assigns page objects without an isRedirect field so _buildPageList ends up
copying undefined; update every pages[...] assignment inside that loop (both the
branch where mw.Title.newFromText succeeds and the two external branches) to
include isRedirect: false (e.g., pages[titleStr] = { title: titleStr, external:
false, isRedirect: false } and pages[page['*']] = { title: page['*'], external:
true, isRedirect: false }) so external entries consistently have isRedirect set.

In `@resources/js/ApiPageConnectionRepo.js`:
- Line 28: The concat call on this._addedPages is non-mutating so
this._addedPages never updates; update addConnections to either assign the
concat result back to this._addedPages (this._addedPages =
this._addedPages.concat(pagesToAdd)) or push the new items into the array
(this._addedPages.push(...pagesToAdd)) so the deduplication using _addedPages
actually works; locate the concat call and replace it with one of these two
approaches in the ApiPageConnectionRepo class so subsequent calls skip
already-added pages.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4ca5b1 and d131313.

📒 Files selected for processing (2)
  • resources/js/ApiConnectionsBuilder.js
  • resources/js/ApiPageConnectionRepo.js

@cicalese
Copy link
Collaborator Author

cicalese commented Feb 25, 2026

The CI failure appears to be unrelated. I'll handle the unrelated CodeRabbit suggestions in another PR, as they are unrelated.

cicalese added a commit that referenced this pull request Feb 26, 2026
Fix issues found by CodeRabbit in #92

- Assign concat result back to _addedPages so the dedup cache
  actually grows across addConnections calls
- Build a redirect map from the API response and use it to resolve
  title icon lookups for redirected pages
- Add isRedirect: false to outgoing and external link page entries
  for consistency with central page and incoming link entries
@cicalese
Copy link
Collaborator Author

cicalese commented Feb 26, 2026

The unrelated CodeRabbit suggestions are handled in #93.

When a page has no custom display title, fall back to the resolved
redirect target title instead of the original redirect source title.
cicalese added a commit that referenced this pull request Feb 26, 2026
Fix issues found by CodeRabbit in #92

- Assign concat result back to _addedPages so the dedup cache
  actually grows across addConnections calls
- Build a redirect map from the API response and use it to resolve
  title icon lookups for redirected pages
- Add isRedirect: false to outgoing and external link page entries
  for consistency with central page and incoming link entries
@cicalese
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
resources/js/ApiPageConnectionRepo.js (1)

155-163: LGTM! Clean helper method with safe null handling.

The defensive check for pageInfoResponse.query.redirects before iteration prevents the TypeError reported in issue #90 when the redirects array is absent.

For extra defensive programming, consider using optional chaining to guard against edge cases where query might be undefined (though currently protected by prior access at line 47):

🔧 Optional: Add optional chaining
 ApiPageConnectionRepo.prototype._buildRedirectMap = function(pageInfoResponse) {
   let redirectMap = {};
-  if (pageInfoResponse.query.redirects) {
-    pageInfoResponse.query.redirects.forEach(function(redirect) {
+  if (pageInfoResponse.query?.redirects) {
+    pageInfoResponse.query.redirects.forEach(function(redirect) {
       redirectMap[redirect.from] = redirect.to;
     });
   }
   return redirectMap;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@resources/js/ApiPageConnectionRepo.js` around lines 155 - 163, The helper
_buildRedirectMap should guard against pageInfoResponse.query being undefined
before accessing redirects to avoid potential runtime errors; update the check
for redirects to use optional chaining on pageInfoResponse.query (i.e., verify
pageInfoResponse.query?.redirects) and iterate only if that value is present,
keeping the current redirectMap population logic in
ApiPageConnectionRepo.prototype._buildRedirectMap.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@resources/js/ApiPageConnectionRepo.js`:
- Around line 155-163: The helper _buildRedirectMap should guard against
pageInfoResponse.query being undefined before accessing redirects to avoid
potential runtime errors; update the check for redirects to use optional
chaining on pageInfoResponse.query (i.e., verify
pageInfoResponse.query?.redirects) and iterate only if that value is present,
keeping the current redirectMap population logic in
ApiPageConnectionRepo.prototype._buildRedirectMap.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d131313 and 9cd9198.

📒 Files selected for processing (1)
  • resources/js/ApiPageConnectionRepo.js

@cicalese
Copy link
Collaborator Author

@JeroenDeDauw This should be ready to merge pending your review.

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

Successfully merging this pull request may close these issues.

TypeError: Cannot read properties of undefined (reading 'length') Redirects cause the visualization to break

1 participant