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.
| Comment | File | Size | Author |
|---|---|---|---|
| #30 | redirect-3018897-30.patch | 8.29 KB | daniel.bosen |
| #29 | redirect-3018897-29.patch | 7.37 KB | pookmish |
| #17 | redirect-n3018897-17.patch | 4.52 KB | damienmckenna |
| #15 | redirect_loop-3018897-15.patch | 4.7 KB | miiimooo |
| #14 | redirect_loop-3018897-13.patch | 1.36 KB | balbeeryadav |
Issue fork redirect-3018897
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
Comment #2
nrackleff commentedAttaching the full error text.
Comment #3
nrackleff commentedThe code that is problematic for us is on line 85 of RedirectRepository.php
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?
Comment #4
berdirRight, 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.
Comment #5
nrackleff commentedI'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-votersto/node/6271, but since the path on the new site is also/document/league-women-votersthe 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-votersto/node/6271again.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.
Comment #6
tim.clifford commentedPatch which removes the exception from being thrown when there is duplicate redirects, but instead logs the error instead and returns out.
Comment #7
fjgarlin commentedComment #9
tim.clifford commentedComment #10
fjgarlin commentedComment #11
kyuubi commentedHi 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.
Comment #12
berdirOpen 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.
Comment #13
balbeeryadav commentedFacing the same issue in my project. Any update or better approach suggested for this issue?
Comment #14
balbeeryadav commentedCreated a patch without logging and compatible with D8.9
Comment #15
miiimoooAttached 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.
Comment #16
ahmad abbad commented#15 works for me, Thank you!
core v= 9.3.13
redirect v = 1.7
Comment #17
damienmckennaRerolled; most of the changes were in the test file.
Comment #19
pflora commentedI couldn't apply the patch from #17, and since it isn't passing all the tests i'll try and work on it!
Comment #20
pflora commentedLooking 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.
Comment #21
pookmish commentedI've adjusted patch from comment 20 since it was incorrectly using the create method and not using interfaces which caused a WSOD.
Comment #22
pookmish commentedRe-rolled the patch from #21 due to the 1.9 release
Comment #23
jiong_ye commentedattempt to fix Error: Class "Drupal\redirect\FormattableMarkup" not found in patch #22
Comment #24
jiong_ye commentedComment #25
jiong_ye commentedfix logger
Comment #27
berdirThere 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.
Comment #28
pookmish commentedRe-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.
Comment #29
pookmish commentedRe-rolling again for 1.12
Comment #30
daniel.bosenThe 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.
Comment #31
sagesolutions commentedPatch #30 applies properly to 8.x-1.12 and fixes the issue for me. Marking as RTBC
Comment #32
berdirA patch can not be RTBC. The MR still needs work.
Comment #34
daniel_j commentedI 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.
Comment #35
sagesolutions commentedMR #92 does not work with version 1.13, which is now the latest release.
Comment #36
joegl commentedI 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?
Comment #37
sagesolutions commented#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