We have a site with migrated content. When we migrated the content from D7 site, we created redirects from the path on the old site to the node on the new site - in case the paths were not the same. For example, redirect from /document/league-women-voters to /node/6271. Things have been working fine with no redirect loops (even when old website path and new website URL alias are the same) until we open one of these old migrated nodes and attempt to change it's title. If I change the title of the node to that it's new url would be /document/foo and save, I often see the following error:

The website encountered an unexpected error. Please try again later. Drupal\Core\Entity\EntityStorageException: Redirect loop identified at
/document/league-women-voters for redirect 2268 in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save()
(line 783 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Drupal\redirect\RedirectRepository->findByRedirect(Object, 'en') (Line: 93)
Drupal\redirect\RedirectRepository->findMatchingRedirect('document/league-women-voters', Array, 'en') (Line: 109)
redirect_path_update(Array)'

The error doesn't happen 100% of the time on every node. But when it does, it is a WSOD and sometimes it appears that the document title does get changed, but there is no revision history and clearing the cache causes the change to revert.

Issue fork redirect-3018897

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

nrackleff created an issue. See original summary.

nrackleff’s picture

StatusFileSize
new3.98 KB

Attaching the full error text.

nrackleff’s picture

The code that is problematic for us is on line 85 of RedirectRepository.php

if (in_array($rid, $this->foundRedirects)) {
        throw new RedirectLoopException('/' . $source_path, $rid);
      }

If an existing redirect is found, it seems it doesn't necessarily need to throw and exception. Couldn't it just ignore the existing one and not create another one?

berdir’s picture

Status: Active » Postponed (maintainer needs more info)

Right, but what exactly is the backtrace that that you see from that exception if you enable verbose logging?

It would also be useful to have steps to reproduce, I suspect it has something to do with renaming a node multiple times in a row and then back to the original name, resulting in a redirection loop.

nrackleff’s picture

I'm sorry, I can no longer reproduce because we wrote a script to delete the redundant redirects. My guess is that having the unnecessary redirects that we created during the migration caused the problem. For example, during the migration, we created a redirect from the old site path of /document/league-women-voters to /node/6271, but since the path on the new site is also /document/league-women-voters the redirect was unnecessary to begin with, but caused no harm.

Then, when a content editor attempted to change the title of the page and the path changed to /document/league-women-voters-updated, the error was thrown when the system attempted to redirect from /document/league-women-voters to /node/6271 again.

Perhaps an attempt to create a duplicate redirect should just not create the duplicate and post a message rather then throwing an error if that is possible. Thank you for your help.

tim.clifford’s picture

StatusFileSize
new1.47 KB

Patch which removes the exception from being thrown when there is duplicate redirects, but instead logs the error instead and returns out.

fjgarlin’s picture

Status: Postponed (maintainer needs more info) » Needs review

Status: Needs review » Needs work

The last submitted patch, 6: redirect_loop-3018897-6.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

tim.clifford’s picture

StatusFileSize
new1.49 KB
fjgarlin’s picture

Status: Needs work » Needs review
kyuubi’s picture

Hi guys,
I stumbled across this issue as I have another separate problem caused by the same code. Basically, because that array isn't scoped to the current request, multiple passes trigger this exception incorrectly (e.g using subrquests with GraphQL).

I opened a separate issue in #3061173: scope foundRedirects to the current request from the request stack and I can see someone else stumbled into similar problems in #3059894: Redirect loop can occur in sub-requests

I guess what I'm saying is there seems to be multiple scenarios where this exception being triggered causes problems, so this patch would be definitely welcome.

berdir’s picture

Status: Needs review » Needs work

Open to changing this to avoid an exception, but I think this might result in multiple logs when trying to access such a page?

Also, the expectations in the tests need to be updated.

balbeeryadav’s picture

Facing the same issue in my project. Any update or better approach suggested for this issue?

balbeeryadav’s picture

StatusFileSize
new1.36 KB

Created a patch without logging and compatible with D8.9

miiimooo’s picture

Version: 8.x-1.3 » 8.x-1.7
StatusFileSize
new4.7 KB

Attached is a re-rolled version of the patch where I have also moved the redirect prevent from a class member to an additional argument that gets passed through the recursive calls to findMatchingRedirect and findByRedirect, to avoid any parallelism issues.

I've also updated the automated test to reflect the difference in behaviour.

I'm not sure this is the right way to go about solving the original issue. Maybe there is a way to catch the RedirectLoopException before it breaks the node saving.

Also, would be good to add a test for the original issue.

ahmad abbad’s picture

#15 works for me, Thank you!
core v= 9.3.13
redirect v = 1.7

damienmckenna’s picture

Status: Needs work » Needs review
StatusFileSize
new4.52 KB

Rerolled; most of the changes were in the test file.

Status: Needs review » Needs work

The last submitted patch, 17: redirect-n3018897-17.patch, failed testing. View results

pflora’s picture

Assigned: Unassigned » pflora

I couldn't apply the patch from #17, and since it isn't passing all the tests i'll try and work on it!

pflora’s picture

Assigned: pflora » Unassigned
StatusFileSize
new6.92 KB

Looking through the changes made in patch #17 I noticed that the findMatchingRedirect() method now doesn't treat the redirect infinite loop. If we try to access a node that has a redirection lopp it'll break the website. This is why the functional tests were getting errors and the Kernel test was not getting the expected URL.

I'm sending a patch with some changes. I'm not very familiar with this module, but I suppose we could try to redirect the node with an infinite loop to a 404 page, and log the error. I did not change the tests, though, since I do not know if this is the correct aproach.

If there is anything that could be changed, feel free to give me any kind of feedback and i'll try to work on it. Also, if this solution is acceptable, I'm willing to work to adapt the tests.

pookmish’s picture

StatusFileSize
new2.63 KB
new6.42 KB

I've adjusted patch from comment 20 since it was incorrectly using the create method and not using interfaces which caused a WSOD.

pookmish’s picture

StatusFileSize
new6.2 KB

Re-rolled the patch from #21 due to the 1.9 release

jiong_ye’s picture

StatusFileSize
new6.24 KB

attempt to fix Error: Class "Drupal\redirect\FormattableMarkup" not found in patch #22

jiong_ye’s picture

StatusFileSize
new6.24 KB
jiong_ye’s picture

StatusFileSize
new6.27 KB

fix logger

berdir’s picture

There are 20 open issues with the word "loop" in them, for example #3401916: Redirect loop wrong detection (service unavailable: RedirectLoopException), helping to identify duplicates, closing them and agreeing on the best solution between this and the other issue would be really helpful.

pookmish’s picture

StatusFileSize
new6.31 KB

Re-rolling the patch to be used in composer.json patches for version 1.10. I'm not creating a MR since there seems to be a lack of clarity on the direction of the desired solution at this time.

pookmish’s picture

StatusFileSize
new7.37 KB

Re-rolling again for 1.12

daniel.bosen’s picture

StatusFileSize
new8.29 KB

The patch in #29 causes the following error: TypeError: Drupal\redirect\RedirectRepository::__construct(): Argument #4 ($logger_factory) must be of type Drupal\Core\Logger\LoggerChannelFactoryInterface.
I created a new patch which resolves this errors.

sagesolutions’s picture

Version: 8.x-1.7 » 8.x-1.12
Status: Needs work » Reviewed & tested by the community

Patch #30 applies properly to 8.x-1.12 and fixes the issue for me. Marking as RTBC

berdir’s picture

Status: Reviewed & tested by the community » Needs work

A patch can not be RTBC. The MR still needs work.

daniel_j made their first commit to this issue’s fork.

daniel_j’s picture

I merged 8.x-1.x into this branch and resolved conflicts. I also moved all newly-introduced arguments to the end of function signatures rather than adding them in the middle.

sagesolutions’s picture

Version: 8.x-1.12 » 8.x-1.13

MR #92 does not work with version 1.13, which is now the latest release.

joegl’s picture

I am not having a problem applying what's in the merge request to 1.13 as patch (using the diff generated: https://git.drupalcode.org/project/redirect/-/merge_requests/92.diff).

Perhaps you have a conflict with another patch?

sagesolutions’s picture

Status: Needs work » Reviewed & tested by the community

#30 patch works with version 1.12. Note that patch #30 does not work with version 1.13

MR #92 applies properly to version 1.13. Marking as RTBC