Problem/Motivation
This issue started to address a problem where a migration was aborting, after 2 hours, on d6_menu_links. @lostkangaroo noticed that children were being migrated before the parent. The initial patch which ordered the query on depth and threw and exception if the link was not the first was being used successfully.
Later on an IRC discussion (#10), it was suspected that paths are not being migrated as expected and that the plugin should be more defensive. Which is now the focus of this issue. That discussion resulted in adding code to rebuild the routes, if needed, validate the path, and throw an exception if the path is not routed.
We realized on validation of paths, it tried to continue migrating them even if they fail.
In the meantime #2816857: Process plugin link_uri shouldn't be in d6 namespace got in, which uses Url::from Uri, which will validate the path.
Proposed resolution
Throw an exception, which gets converted to a message, and doesn't stop the migration and discard the link if it fails validation.
--- Original Issue Summary ---
All,
I am now able to reproduce an error wherein drupal migrate-upgrade aborts at about the 2-hour mark. The error.
Importing d6_menu_links PHP Fatal error: Call to a member function getUrl() on null in /var/www/html/core/modules/menu_link_content/src/Entity/MenuLinkContent.php on line 83 Drush command terminated abnormally due to an unrecoverable error. [error] Error: Call to a member function /src/Entity/MenuLinkContent.phgetUrl() on null in /var/www/html/core/modules/menu_link_content p, line 83
I am putting this in as a support request as I am hardly sure that it has anything specific to do with migrate_upgrade since the error seems to do only with the menu_link_content element/module. I don't find any reference to a bug report or issue about this. Where would you take this if you were me?
Secondarily, I figured I would modify the migration list to avoid any d6.menu.* migrations to see if I could get it to complete. I figured I would just modify the /migrate_upgrade/migrate.config.yml but that seemed to have no effect (as a test I reduced that file to 10 migrations yet it is clearly running all of them right now).
drush migrate-manifest is deprecated but still available in migrate_tools. migrate_upgrade doesn't appear to have a parameter to specifiy a manifest. What should I be editing to modify/limit migrations by migrate_upgrade? Or should I be using a mix of migrate_tools and migrate_upgrade?
Thanks for the attention and patience!
Jim
| Comment | File | Size | Author |
|---|---|---|---|
| #71 | interdiff.txt | 954 bytes | joelpittet |
| #71 | 2551727-71.patch | 12.28 KB | joelpittet |
| #65 | interdiff.txt | 2.97 KB | quietone |
| #65 | menu_link_migrations-2551727-65.patch | 12.25 KB | quietone |
| #62 | interdiff-60-62.txt | 620 bytes | jofitz |
Comments
Comment #3
mikeryanmigrate_upgrade has nothing specific to menu links, so I'm sure the root of that problem is in the core menu link migration support. Moving to the core issue queue.
The manifests are no longer used, I've now removed them, thanks for pointing that out.
To customize the migrations to import, run the migrate-upgrade command with --configure-only which creates all the migrations from the templates - then you can use migrate-import to selectively run migrations.
In terms of the d6_menu_links problem, if you could narrow it down by running only d6_menu and d6_menu_links, and maybe provide info on the links it's attempting to migrate, that would help.
Thanks.
Comment #4
mikeryanComment #5
lostkangaroo commentedWe have been using this patch locally at APQC for about a month to solve this issue. We noticed that children were attempting to be migrated before the parent causing the error since the parent doesn't exist on the destination. By ordering on depth we solved this somewhat but would welcome some more test runs in different environments to see if this does in fact fix this issue.
Comment #6
geste commented@mikeryan @lostkangaroo
Thank you. Much improved quality-of-Monday here!
Jim
Comment #7
geste commented@lostkangaroo
Your patch worked and a full migration of D6 site completed without error. So I did not go back and selectively migrate the d6_menu and d6_menu_links.
Pages/nodes not rendering yet but I have a usable /admin, so time to bone up on more selective, scripted use of migrate-upgrade/import.
I reiterate: This is awesome! :)
Jim
Comment #8
lostkangaroo commentedIn light of #7 lets go RTBC with this.
Comment #9
webchickUm. :)
Also, let's get some test coverage for this.
Comment #10
phenaproximaAfter discussing with @neclimdul and @lostkangaroo on IRC, here's a patch that may help. My suspicion is that paths are not being migrated in as expected, and certain menu links are therefore imported with invalid paths. It's a shot in the dark, though.
This patch makes d6_menu_links more defensive, validating link paths and skipping rows if they fail.
Comment #12
phenaproximaForgot a semicolon.
Comment #16
lostkangaroo commentedAdded patch #12 to our long run dataset lets see what we get.
Comment #17
phenaproximaThis should pass the tests. #12 can be considered the fail patch.
Part of the issue here is that the d6_menu_links and d7_menu_links migrations don't bother to validate if the path being migrated exists at all. This here patch makes both migrations more defensive -- it beefs up the internal_uri process plugin so that it does a lookup of the link's path, allowing the row to be skipped if the path doesn't exist.
Comment #18
neclimdulI don't like this approach because it leaves no reference for why the row was skipped. This leaves migrators to wallow through code looking for how they can fix their migration.
Comment #20
neclimdulheh, pifr isn't comming back on that one. requeued in drupalci
Comment #21
neclimdulwhat about this?
Comment #22
phenaproximaI don't really have RTBC privileges for this patch, but +1 for RTBC.
Comment #23
neclimdulI'd RTBC as well but we didn't add any tests...
Comment #24
chx commentedWhy are we using an array of sources instead of just source: link_path...? Odd. Get certainly has $properties = is_string($source) ? array($source) : $source; so it doesn't care a lot.
Comment #25
quietone commentedRemoved the array of sources as per #24. Added some tests.
There is a failure in D7, from a pre existing test, related to the link 'admin/content/book'. I suspect that the link is now found to be invalid, after all the book module is not installed. Perhaps, a different custom link should be created and added to the fixture.
Comment #26
quietone commentedComment #28
benjy commentedHow come only the D7 version needs the regex when iterating the map table?
Missing new line.
I think these were added by accident.
Comment #29
quietone commented1. The D7 dump contains several invalid links and thus several messages are in the message table while the D6 dump doesn't have any invalid links. An invalid link needs to be inserted in the source. But I changed them to be the same. That way, the next person doesn't have to figure out why they are different. And it wouldn't hurt if the D6 test looped through the message table.
2. Fixed
3. Fixed
Also, changed the source for the D7 customized link test from 'admin/content/link' to 'admin/config/system/site-information'. This ensures the link is valid for testing in d7/MigrateMenuLinkTest.php.
Comment #30
benjy commentedOK, this looks good, i'd mark RTBC but do you think we should get #2648996: Optimize menu link migration in first which is going to conflict and is already RTBC?
Comment #31
quietone commentedYes, agreed.
Comment #33
mikeryanCurrently waiting on #2648996: Optimize menu link migration.
Comment #34
quietone commented#2648996: Optimize menu link migration is in so no longer postponed.
Comment #35
quietone commentedRerolled.
Comment #36
quietone commentedComment #38
mikeryanRather than reaching out to the executable to save a message (and add an extra step to the pipeline), it would be simpler (and consistent with how error handling is meant to work) to just throw a MigrateException for the invalid path.
Comment #39
imiksuNow throws MigrateException.
Comment #40
imiksuComment #42
quietone commentedChanged unit test to handle the exceptions.
Comment #44
quietone commentedAh, I'm all thumbs today.
Comment #45
heddnLet's update the issue summary. I'd like to see the new test added in #42 converted to a kernel test so we can call an actual PathValidator service. Otherwise, we aren't really seeing what types of errors could get thrown from that thing when we use a mock.
Comment #46
quietone commentedConverted the plugin test to a Kernel test. Removed the changes to the test fixture that aren't needed anymore and the tests for map messages since an exception is being thrown. The interdiff is large because of all the deletions.
Comment #48
jofitzmlid 478 is failing to migrate because its path (
admin/content/book) does not exist in D8. Avoid the complication of involving thebookmodule by simplifying the path of mlid 478 toadmin/contentwhich we can guarantee is routed.Comment #49
quietone commentedI disagree. I think the source data needs to have what Drupal7 really has, not fudge to suit our test. We should keep the 'real' D7 data and prove that link isn't migrated.
Comment #50
jofitzThe menu link in question (mlid 478) is not part of 'real' D7 data; it was added as part of the testing for #2589237: Menu links parent migration is broken. It's path is not actually relevant, so a minor tweak to retain a test for
internal:/abc/xyzlinks is justifiable.Comment #52
quietone commentedOK, thanks for that. I should have checked first.
Comment #53
mikeryanComment #54
mikeryanAssuming the 8.3.x/8.4.x tests I started come back clean, I think this is good to go.
Comment #55
alexpottThe 8.4.x and 8.3.x tests on #48 have failed - and the reason looks patch related.
Comment #56
jofitzJust needed a minor change to the fixture because the route node/3 no longer exists. There should be no repercussions to this fixture edit because this entry was specifically added (by me!) as part of #2669978: Migrate D7 Menu Links.
Comment #57
joelpittetAdded 8.4.x test but it looks as though that should pass too. Re-setting to RTBC
Comment #58
alexpottI think we should document why we do this. Also why do we do this? What is happening that requires the route rebuild?
Dropped? I'm not sure what that actually means with respect to a migration.
Comment #59
heddn58.2 has been in the code for a while. I think since #17 2 years ago. I'd hazard a guess it isn't needed.
58.3 probably means we loose the data and do not import it. Let's try "The path "%s" failed validation" instead. Just drop the last part, pun intended.
Comment #60
jofitz$isRouterRebuiltsection and consequently all references to that and$routerBuilder.@heddn-- for a dreadful pun!
Comment #61
heddnThat seems like a long time to have tests queued. 6 hrs? Otherwise, one small nit before tests come back.
Unused import.
Comment #62
jofitzThanks, @heddn. I can't believe I missed that one - I'd removed most of the other changes in that file!
Comment #63
heddnMarking RTBC based on #60 passing. #62 isn't any different, except for removal of an unused import.
Comment #64
alexpottDoesn't look like the test is actually running. Or at least this is not being tested for.
Comment #65
quietone commentedTest fixed!
Comment #66
heddnAssigning to myself to review this week.
Comment #67
quietone commentedI neglected to say how I fixed the test. Method providerTestNotRouted was providing 3 arguments to testNotRouted which was expecting 2 arguments. Method providerTestNotRouted is now providing 2 arguments. And the exception message now reflects what is actually i the process plugin.
The interdiff shows changes to drupal7.php even though I made no changes to the test fixture.
Comment #68
heddnTest changes in #50 and #56 make sense. Interdiff does seem odd, but reviewing the actual patch, appropriate updates have been done to providerTestNotRouted and testNotRouted.
The defensiveness already is in. See #2816857: Process plugin link_uri shouldn't be in d6 namespace. This patch is just about adding more tests and throwing an exception on a bad link. It does that. Looks good to me.
Comment #69
heddnComment #70
catchThis failed phpcs, could use a quick re-roll for that.
Could also do with an issue summary update to more clearly explain what the current bug is and how it's fixed. I think from reading the patch that while we were validing paths, we were still migrating them even if they fail - now we throw an exception (gets converted to a message, doesn't stop the migation) and discard the link if it fails validation - but the issue summary doesn't actually say this.
Comment #71
joelpittetComment #72
heddnNit fixed. Issue summary updated. I'm optimistic that the comment changes won't break anything. So back to rtbc.
Comment #74
catchCommitted/pushed to 8.5.x and cherry-picked to 8.4.x. Thanks!