Hi, I've installed AMP module (latest 3.x-dev version) and I've got a critical error on all pages (even on admin pages).
I'm using latest D 8.7.8.
The error is:
The website encountered an unexpected error. Please try again later.
TypeError: Argument 5 passed to Drupal\amp\Asset\AmpCssCollectionRenderer::__construct() must be an instance of Drupal\Core\Asset\CssOptimizer, instance of Drupal\cdn\Asset\CssOptimizer given, called in /var/www/html/web/core/lib/Drupal/Component/DependencyInjection/Container.php on line 285 in Drupal\amp\Asset\AmpCssCollectionRenderer->__construct() (line 69 of modules/contrib/amp/src/Asset/AmpCssCollectionRenderer.php).
Drupal\amp\Asset\AmpCssCollectionRenderer->__construct(Object, Object, Object, Object, Object) (Line: 285)
Drupal\Component\DependencyInjection\Container->createService(Array, 'asset.css.collection_renderer') (Line: 173)
Drupal\Component\DependencyInjection\Container->get('asset.css.collection_renderer', 1) (Line: 487)
Drupal\Component\DependencyInjection\Container->resolveServicesAndParameters(Array) (Line: 237)
Drupal\Component\DependencyInjection\Container->createService(Array, 'ajax_response.attachments_processor') (Line: 173)
Drupal\Component\DependencyInjection\Container->get('ajax_response.attachments_processor', 1) (Line: 487)
Drupal\Component\DependencyInjection\Container->resolveServicesAndParameters(Array) (Line: 237)
Drupal\Component\DependencyInjection\Container->createService(Array, 'ajax_response.subscriber') (Line: 173)
Drupal\Component\DependencyInjection\Container->get('ajax_response.subscriber') (Line: 105)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.request', Object) (Line: 127)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 693)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
| Comment | File | Size | Author |
|---|---|---|---|
| #21 | 3094944-cssoptimizer-conflict.patch | 14.64 KB | karens |
| #19 | 3094944-cssoptimizer-conflict.patch | 14.69 KB | karens |
| #17 | 3094944-cssoptimizer-conflict.patch | 14.28 KB | karens |
| #15 | 3094944-cssoptimizer-conflict.patch | 10.07 KB | karens |
| #14 | 3094944-cssoptimizer-conflict.patch | 4.55 KB | karens |
Comments
Comment #3
karens commentedI can't replicate any problem but I see a typo in the use statement that might be the cause, so fixing that.
Comment #4
finex commentedThankyou, I will try the new module soon :-)
Comment #5
dave reid@KarenS I think the constructor should typehint on the AssetOptimizerInterface, type hints for specific classes should be avoided if possible. If the CDN module doesn't extend this core class (and it shouldn't have to), this will still fail.
Comment #6
multidimension commentedI'm having the same error on the latest Drupal 8.9.3, although with a different optimizer:
TypeError: Argument 5 passed to Drupal\\amp\\Asset\\AmpCssCollectionRenderer::__construct() must be an instance of Drupal\\Core\\Asset\\CssOptimizer, instance of Drupal\\vendor_stream_wrapper\\Asset\\VendorStreamWrapperAssetOptimizer given, called in /var/www/vhosts/shoppinginromania.ro/core/lib/Drupal/Component/DependencyInjection/Container.php on line 259
I need to have vendor_stream_wrapper enabled as it's required for ColorPicker.
The site is running on PHP 7.2.31
Looking at vendor_stream_wrapper it implements AssetOptimizerInterface.
Any ideas? Would it have anything to do with my environment?
Comment #7
karens commentedClarifying the problem, I think Dave is right, need to change CssOptimizer to CssOptimizerInterface in the constructor.
Comment #8
karens commentedAnd there's no patch so it's not "Needs work".
Comment #9
jrsouth commentedUtterly naive patch attached, swapping out references to
Drupal\Core\Asset\CssOptimizerin favour ofDrupal\Core\Asset\AssetOptimizerInterface.Patching against commit 09bb5f4 on 8.x-3.x
Only "tested" insofar as my site no longer displays the error, and the AMP version of my pages validate okay.
Definitely needs further attention, but this appears to have got me over the line for today.
Update:
Ah. Spoke far too soon, further errors still being reported (but at least there's no white screen of death...):
Comment #10
jrsouth commentedAnother naive, minimally-tested workaround, this time for the warning in #9
Wraps the
preg_replace_callback()call in a conditional that just checks for arewriteFileURI()method on$this->optimizerbefore running.Essentially untested ― I don't have any
url()s within my AMP theme ― but I assume the cdn module takes care of URL replacement as part of its implementation ofDrupal\Core\Asset\AssetOptimizerInterface::optimize(), and any CssOptimizer implementation that does need to run the replacement regex will provide a suitablerewriteFileURI()method, and therefore run the conditional replacement code.Comment #11
karens commentedI think this is the only way to go. It looks like the CDN module does not use that method. The note on that method in Drupal\Core\Asset\CssOptimizer looks like it was deliberately left out of the interface. I don't have any way to test what happens in the CDN module to see if urls in css work without this or not.
I guess the other solution would be adding something like "if not method exists" then create the functionality in this module instead. Or maybe do that anyway, copy that method to this class but rename it, then use the renamed method so it's always available and there's no conflict either way.
Comment #12
karens commentedOK, the only method we're using is the one that isn't in the interface. So rather than this fix we should remove the CSSOptimizer altogether. Then copy the method we want into our class (code duplication but there's no way around it). Then use the new method. No other module decorating the optimizer will be impacted.
Comment #13
karens commentedComment #14
karens commentedAdd a little more documentation about the issue for future reference.
Comment #15
karens commentedRealized we only need to use this if css files have not been aggregated, so I reworked the logic. If files are aggregated the code won't change anything so it didn't hurt anything but is not necessary. I also added a test that the css gets altered correctly.
Comment #17
karens commentedComment #19
karens commentedComment #21
karens commentedComment #23
karens commentedCommitted, thanks!