Problem/Motivation
An old migration configuration, using migrate_plus and migrate_source_csv, used the following definition for migration dependencies. This old, malformed migration_dependencies broke all migrations. This is on 8.1.10 and latest versions of migrate_plus.
migration_dependencies:
- csv_migrate_story
whereas it should have looked more like:
migration_dependencies:
required:
- csv_migrate_story
So, even though it wasn't related to the new migration, it caused the following exception, making me thing there was something wrong with the new migration:
TypeError: Argument 1 passed to Drupal\migrate\Plugin\MigrationPluginManager::expandPluginIds() must be of the type array, string given in [error]
Drupal\migrate\Plugin\MigrationPluginManager->expandPluginIds() (line 138 of
/var/www/drupalvm/web/core/modules/migrate/src/Plugin/MigrationPluginManager.php).
TypeError: Argument 1 passed to Drupal\migrate\Plugin\MigrationPluginManager::expandPluginIds() must be of the type array, string given in /var/www/drupalvm/web/core/modules/migrate/src/Plugin/MigrationPluginManager.php on line 138
TypeError: Argument 1 passed to Drupal\migrate\Plugin\MigrationPluginManager::expandPluginIds() must be of the type array, string given in Drupal\migrate\Plugin\MigrationPluginManager->expandPluginIds() (line 138 of /var/www/drupalvm/web/core/modules/migrate/src/Plugin/MigrationPluginManager.php).
Proposed resolution
Give a more meaningful error message when migration_dependencies isn't structured correctly.
Remaining tasks
Code it.
User interface changes
n/a
API changes
n/a
Data model changes
n/a
Comments
Comment #2
rachel_norfolkComment #3
heddnComment #4
nickdickinsonwildeRan into approximately this issue (actually a missing space between a dash and the name meant it was a string instead of an array, but close enough)... Adjusted to report an error like so (when run through drush):
I suppose the question would be if it needs a test?
Comment #5
heddnThese changes seem reasonable. A couple small points and this should be ready. Tagging novice. We could also use tests. It is debatable if test part is novice, but the rest is.
This seems random?
Let's throw an InvalidPluginDefinitionException instead?
Comment #6
vacho commentedOnly for contribute to discussion of this enhancement.
Whats mean string620? In all code I don't found other part with this code.
IMO it is right because this is not a plugin exception and this exceptions is used for Migrate proccess.
Comment #7
littlepixiez commentedThanks for the patch @NickWilde! #4 works great for me.
I presume the string620 might have been an accident. I've just updated it to throw an InvalidPluginDefinitionException but am happy to change it back to a MigrateException? I also fixed the !is_array check to check required as well as optional.
I have given the test a go... I've never contributed a test before so I'm not sure if I've approached it correctly, I've tried to get inspiration from migrate and other core modules, so any feedback would be appreciated!
Oops.. Will fix deprecation tomorrow!
Comment #8
littlepixiez commentedHere's an updated version with deprecation fix. I was testing on an older version of core stupidly! Also I'm getting:
1) Drupal\Tests\migrate\Kernel\process\DownloadTest::testOverwritingDownload
mkdir(): No such file or directory
(separate issue)
Locally, but this is with and without the attached patch...
Comment #9
nickdickinsonwildeThanks! Setting status to NR - to trigger the test bot.
Comment #10
nickdickinsonwilde(and yes that 620 was just random characters that somehow got in there... someone (me) didn't properly review the actual patch file before posting apparently)
Comment #11
nickdickinsonwildeBest to include a patch only thing that fails... test-only copy of latest patch.
Real patch is just a re-upload of @littlepixiez' latest patch.
Comment #13
heddnDebatable, but let's add a CR explaining that an exception is now thrown if the format of migration_dependencies is wrong.
And I think we need to also support the following scenarios without throwing exceptions:
non-existent
migration_dependenciesempty array of
migration_dependencies = []and single array entries
migration_dependencies = ['required' => 'd6_node']Comment #14
littlepixiez commentedThanks for the feedback guys!
This line:
$this->migration_dependencies = ($this->migration_dependencies ?: []) + ['required' => [], 'optional' => []];seems to ensure we won't get an exception thrown for any of those scenarios and it will still return the correct array even if it's non-existent, empty or provides only required/optional (but required/optional still need to be provided as an array).
I've added another test to cover these scenarios to ensure this isn't broken, if that's helpful.
@NickWilde presumably putting both up means you are making sure the test fails before, and succeeds after?
Thanks for your patience! :) Also not entirely sure about how to add a change record?
Comment #15
quietone commented$migration->id() returns NULL.
$this->id() returns NULL
Perhaps get('id') is needed in both cases/
@littlepixiez, thanks for adding extra tests. Yes, the test only patch proves the failure.
There is a handbook page for how to make a change record,
Contributor task: Write up a change record for a Drupal core issue
Comment #16
littlepixiez commentedHi @quietone. Thanks for the feedback! Oh yes, you're totally right. Considering $this->id() seems to return $this->pluginId, which is set in the constructor originally and has no override method, I've popped a method on the TestMigration class to set the plugin ID, and then tested that the message matches the one that's been set in the test function. When a real migration has invalid configuration set, $this->id() returns the migration machine name as expected too.
Thanks for the handbook page reference, how exciting, I'll have a gander. :)
Comment #17
heddnCode changes here are looking good. Just missing the CR at this point.
Comment #18
littlepixiez commentedHey @heddn. Great! I attempted creating a change record. I wasn't sure whether to explain that before this, it would throw a general error, and that after this it would throw an exception. I also wasn't sure whether to give an example of an incorrectly formatted migration_dependencies (as the most common mistake is forgetting to use optional or required as the key).
Thank you! https://www.drupal.org/node/3077671
Comment #19
quietone commentedHope to do get to this on the weekend.
Comment #20
quietone commented@littlepixiez, thanks for the CR, it does contain the necessary information. Providing examples of all the valid format and stating the required action is great and well covered, I thing. I do think that using an 'if' statement in the Description can be avoided by just stating the case convered here. I don't know maybe, 'Formatting errors in the migration_dependencies property of a migration ....'.
Oh, and should it state the previous behavior when it failed?
Comment #21
quietone commentedComment #22
littlepixiez commentedHi @quietone, so sorry for my really late reply! I've updated the CR now to be a bit more concise. Hopefully I've worded it in a way that makes sense. Thanks so much for your feedback. :) The only thing I'm unsure of is that it wouldn't always necessarily throw a TypeError if they are incorrectly formatted depending on what you actually format incorrectly. So I'm not sure whether specifying the error is appropriate?
Comment #23
heddnLooking good.
Comment #25
heddnUploading #16 again so it is last.
Comment #26
catchCommitted 3cfe0f0 and pushed to 8.8.x. Thanks!
Comment #28
catchFixing credit.
Comment #29
larowlanIs this accurate?
Comment #30
larowlanMissed that this had been committed to d8 - I think this is the correct status
Comment #31
damienmckennaThe patch in #25 applies pretty cleanly against 8.7.x as-is.
Comment #32
damienmckennaWhile I appreciate that it now throws an appropriate error instead of just barfing all over my terminal, IMHO it would have been nicer if each item had allowed NULL values too, especially for beginners (or experienced folks who forget). I'll probably open a new issue for this request.
Comment #33
damienmckenna#25 rerolled for 8.7, because testbot.
Comment #35
larowlan8.7 is security only now
Comment #37
farnoosh commentedWhat is the reason for adding
count($this->migration_dependencies) !== 2to the condition statement?Comment #38
farnoosh commentedignore this comment, please.
Comment #39
farnoosh commentedOnly removing the count($this->migration_dependencies) !== 2 in this patch.