Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
While working on #2565931: Handle long comment bundle names I discovered that the migrate lookup service throws a PluginNotFoundException with the default message which assumes the plugin_id is a string but for migratelookup it can be an array. This results in the error
1) Drupal\Tests\migrate_drupal_ui\Functional\d7\DoubleSlashTest::testMigrateUpgradeExecute
Exception: Notice: Array to string conversion
Drupal\Component\Plugin\Exception\PluginNotFoundException->__construct()() (Line: 22)
Steps to reproduce
Proposed resolution
Use a custom message in the migratelookup service when the PluginNotFoundException is thrown.
Remaining tasks
Patch
Review
Commit
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#21 | 3187386-21.patch | 3.95 KB | quietone |
#21 | interdiff-18-21.txt | 1.07 KB | quietone |
#18 | 3187386-18.patch | 3.95 KB | quietone |
#18 | interdiff-16-18.txt | 624 bytes | quietone |
#16 | interdiff_14_16.txt | 468 bytes | anmolgoyal74 |
Comments
Comment #2
quietone CreditAttribution: quietone as a volunteer commentedAnd here is a start. The custom message is just a copy of what is used in PluginNotFoundException and I think it needs improvement. Any suggestions?
Comment #3
quietone CreditAttribution: quietone as a volunteer commentedFix typos is title
Comment #4
quietone CreditAttribution: quietone as a volunteer commentedHmm, my changes were not saved. Try again.
Comment #5
benjifisherInstead of
how about something like this?
Variant:
We might even use
"', '"
as the first argument toimplode()
, leading to an error message likeShould we consider making that change in the PluginNotFoundException constructor? How common is this pattern of looking up one or several plugins by ID?
I searched the core migration modules for "PluginNotFoundException" trying to answer that question. It is too close to my bed time for me to create any new issues, but here are some notes:
{@inheritdoc}
and regular comments.I did not find any other examples of the one-or-several (
string
orstring[]
) pattern, so maybe changing the PluginNotFoundException constructor is not a great idea.Comment #6
quietone CreditAttribution: quietone as a volunteer commentedI agree that making a change in the constructor of PluginNotFoundException is not the way forward. I think the best we can do is what you have suggested which I have implemented in this patch. I also added array keys to the arrays in the data provider. No interdiff because the patch is so small.
1. I have looked at MigrateLookup tests and the MigrateStub tests and agree that the Kernel test is not adding any additional testing. I agree it is not needed and that the Unit tests are sufficient.
2. Yes, that needs some cleanup.
While it isn't late for me I have other plans for the day and can't make new issue right now.
Comment #7
benjifisherI created #3187794: Remove redundant kernel tests in the Migrate module and supplied a patch. I was going to add an issue for #5.2, but first I checked when the doc block was added. It was discussed in #3004456-25: Add a weighting option to MigrateField plugin's definition and lower weight of deprecated 'date' plugin so it isn't used and the following comment. I guess that implementation details should not be added to the interface, and moving some lines from the doc block to regular comments (including one
@see
comment) would mean that they no longer show up in the API docs.Back to this issue!
The testbot approves, the code looks good, and the exception messages are a lot easier to read than in the original patch. RTBC
Comment #8
alexpottNeeds a reroll.
Comment #9
quietone CreditAttribution: quietone as a volunteer commentedAnd the reroll, it was straightforward.
Comment #10
benjifisherSorry, I added that line in #3187794: Remove redundant kernel tests in the Migrate module. The earlier patches on this issue already asserted the exception message supplied by the data provider. The reroll removes the assertion of a static exception message.
Back to RTBC.
Comment #11
catchShould we do:
when determining the message, so that the array of one item gets treated as singular?
Comment #12
quietone CreditAttribution: quietone as a volunteer commentedIf you like. We still need to convert the array to a string when there is only one item in the array.
Comment #13
benjifisherThis is still problematic. The constructor for PluginNotFoundException ignores the
$plugin_id
parameter if a non-empty message is given, so the patches here prevent an error. But the@param
comment specifies that$plugin_id
is a string. Sooner or later, we will enforce that with a type declaration. The patch in #12 replaces a one-element array with a string, but still passes an array when there are multiple plugin IDs.Also,
$migration_ids[0]
will not work if$migration_ids = ['a' => 'my_migration']
. It is safer to usereset()
.I was going to say that we could throw one exception for each migration ID on the list, but that does not work.
We could create a chain of exceptions:
I cannot think of a more specific exception to throw when
$migration_ids == []
.The alternative is to come up with a single string to pass to the PluginNotFoundException constructor as
$plugin_id
as well as a string to pass as
$message
.On second thought, I think the best solution, respecting the semantics of PluginNotFoundException, is to throw the more generic PluginException whenever
$migration_ids
is an array andcount($migration_ids) != 1
. When we throw PluginException, we just have to come up with a message; we do not have to make up a single plugin ID.Comment #14
quietone CreditAttribution: quietone as a volunteer commented@benjifisher, All good points!
Here is another attempt, implementing the solution in the final paragraph.
Comment #15
benjifisherThis looks like it will break in the case of an empty array. We certainly want test coverage for that case.Can we add test coverage for the case of an empty array?
Comment #16
anmolgoyal74 CreditAttribution: anmolgoyal74 at OpenSense Labs for DrupalFit commentedAdded tests for an empty array.
Comment #17
benjifisher@quietone: I meant to mention that I like the way you implemented the logic in #14. It is very clear and efficient.
@anmolgoyal74: Thanks for adding the test!
I am sorry I did not notice this in my earlier review:
The method name in the comment does not match the name of the test method. It is a small thing, but we may as well fix it.
Comment #18
quietone CreditAttribution: quietone as a volunteer commented@benjifisher, the thanks goes to your reviews, because of previous reviews I too extra time to find the 'best' way to do that bit. Thanks!
Ah, I did miss one comment fix. All fixed now.
Comment #19
benjifisherWhile we are at it, we should also thank @catch for making us take another look at this issue.
The last nit-pick is resolved ... the last nit is picked? ... so back to RTBC.
Comment #20
alexpottI think this should
Plugin IDs 'foo', 'bar' were not found.
We can use
"', '"
as the glue.The reason being that usual quotes are used to quote a single thing - not multiple things.
Comment #21
quietone CreditAttribution: quietone as a volunteer commented@alexpott, thanks.
This patch changes the glue as suggested in #20.
Comment #22
benjifisherThe patch in #21 makes the improvement requested in #20. Back to RTBC.
Comment #23
alexpottCommitted and pushed c0904f72e1 to 9.2.x and dd85517943 to 9.1.x. Thanks!