Problem/Motivation
Under certain circumstances when creating a new service with new service decorators you can end up with the error
The service "moduleb.service" has a dependency on a non-existent service "modulea.service".
Presently the only way to solve this problem is to create a Service Provider with the following code:
public function alter(ContainerBuilder $container) {
if (!$container->hasDefinition('modulea.service')) {
$container->removeDefinition('moduleb.service');
}
}
There are better ways to address this issue. One potential solution is https://www.drupal.org/project/drupal/issues/3111008 because that will allow service.yml files to set decoration_on_invalid to something other than exception (the default value).
This issue is to provide a smaller solution that will hopefully be easier to get passed.
Steps to reproduce
- Create a Drupal site. Create and install moduleb.
- Create modulea and create a service
- Add a service in moduleb that decorates the service from modulea
After those three steps nothing will function.
Proposed resolution
Add support for Symfony's decoration_on_invalid property in Drupal's YamlFileLoader.
| Comment | File | Size | Author |
|---|---|---|---|
| #13 | drupal-3293926-12.patch | 2.4 KB | kingdutch |
| #3 | 3293926-service-decorates-non-existant.patch | 844 bytes | geekygnr |
Issue fork drupal-3293926
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:
- 3293926-10point4
changes, plain diff MR !9925
- 3293926-service-decorates-non-existant
changes, plain diff MR !9414
Comments
Comment #2
geekygnr commentedI am not really sure which version to apply this to so I picked the most recent but it exists in 9.x as well.
Comment #3
geekygnr commentedLike I said this applies to multiple versions so I am going to test it against a 10.x branch and a 9.x branch.
Comment #4
geekygnr commentedComment #5
m4oliveiAdded a link to symfony docs for
decoration_on_invalid.Comment #6
m4oliveiThinking out loud, could we instead (also?) support the `decoration_on_invalid` property in the services.yaml file and pass it along if provided, but otherwise keep the default?
Just thinking that the silent fail in some cases could be just as perplexing as getting the error and needing to know you need ServiceProvider as a way to get around it...
Comment #7
geekygnr commentedAt present the YmlFileLoader class in Drupal is almost a direct copy and paste of its Symfony parent. I opted to suggest the smallest change here because there are other issues looking to remove the need to copy and paste a class and those seemed like better locations for working through supporting the properties and features not currently supported in Drupal.
Another course I considered was redoing the copy and paste of the YmlFileLoader but I haven't had the chance to fully understand what changes to the file are needed for Drupal.
Comment #8
driskell commentedThe current patch here will not work in 9.5 due to:
Drupal\Core\DependencyInjection\Compiler\DependencySerializationTraitPass
It will still attempt to get the service for a decorated public service and cause an exception.
Comment #9
driskell commentedOK so now that https://www.drupal.org/project/drupal/issues/2531564 is merged, it's not a problem I think anymore
Comment #10
bircherisn't this similar to the problem we had in #2863986: Allow updating modules with new service dependencies?
I am all in favor of not crashing when services are decorated when drupal is installed or updated. But I think once the site is in a running state a missing service is a problem that should not be ignored. So I think the patch here is not a good option.
Comment #13
kingdutchWith the other improvements that were made in Drupal this can now be solved with Symfony's
decoration_on_invalidtag directly. Since the related issue about replacingYamlFileLoaderentirely has hit some speedbumps I think it's worth it to adddecoration_on_invalidsupport to our own YamlFileLoader already.We're seeing that the community is adopting "decorate over extend" more and more and this would be a big DX win by allowing a single property in a YAML file to replace an extra PHP class for optional decoration. It also lessens the gap to Symfony for any future replacement of the YamlFileLoader.
Comment #15
kingdutchForgot to update the IS.
Comment #16
smustgrave commentedWould it be possible to get test coverage for the new exceptions
Comment #17
kingdutchAdded tests :D
Comment #18
longwaveThe MR looks great to me. In general I think we should be bringing in improvements from YamlFileLoader to keep parity with Symfony features, and this is a nice and small self-contained step towards that.
I confirmed that the code added in this patch is a 1:1 copy from Symfony.
Comment #19
godotislateDoes there need to be test coverage that
decoration_on_invaliddoes what it's expected to do for the values"exception"nulland"ignore"? Or is it fine because it's directly copied from Symfony?Also, do we need a CR documenting
decoration_on_invalidcan be set and how to use?Comment #20
longwavesetDecoratedService()is provided by Symfony, I don't think we need explicit coverage to check that Symfony works? We can rely on their tests to do that.If we think a CR is useful then we can add one, but again given this is a Symfony feature then I'm not sure we need it.
Comment #21
godotislateRelying on the Symfony tests makes sense.
I only mention a CR because bringing a Symfony feature like autowiring was documented in a CR. Bringing in
decoration_on_invalidprobably isn't as significant as that, but since there is a delta between Drupal features and Symfony features, and there isn't any use yet ofdecoration_on_invalidin core, it might be useful for there to be documentation that the feature is available in Drupal.Comment #22
kingdutchI think a change record makes sense as per #21.
Moving to "Needs Review" for the CR to be reviewed and approved :) Implementation is unchanged and was approved in #18.
Comment #23
godotislateCR looks good. I also edited the issue title, mostly for a misspelling. Back to RTBC.
Comment #27
larowlanCommitted to 11.x
I think this qualifies as backport eligible to 10.4 under 'Critical API compatibility issues'
I've created an MR to run tests
Comment #29
kingdutchShould this be backported to 10.4.0? I'm not entirely sure what upgrade paths are supported, can site builders go from 10.4.x to 11.0.x or are they expected to jump from 10.4.x to 11.1.x?
Contrib code that would use this would be compatible with
^10.4 || ^11.1only, if we backport (i.e. would break on 11.0 since it's introduced as feature in 11.1).Comment #30
larowlanYes I thought so, but wanted a green MR first
Comment #31
larowlanCommitted to 10.4.x - thanks