Can someone explain me why I get this error when I try to open the settings form?

Patch is in #1948588: Google Analytics 8 upgrade

Error message

Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "drupal\google_analytics\google_analyticssettingsform". in Symfony\Component\DependencyInjection\Container->get() (line 279 of drupal8\core\vendor\symfony\dependency-injection\Symfony\Component\DependencyInjection\Container.php).
The website has encountered an error. Please try again later.

The google_analytics.routing.yml exists and the form file, too. Cleared the cache several time... I have no idea what this message tries to tell me nor do I have any idea what a "Service" is and how I'm able to make it exists. The base code has been copied from Locale module and than customized.

Comments

hass’s picture

Issue summary:View changes

A

hass’s picture

Component:base system» forms system
hass’s picture

Component:forms system» routing system
hass’s picture

Category:support» bug

After a lot of try and error I figured out that the underscore in the class name causes this issue.

google_analytics.routing.yml need to be changed from:

google_analytics_settings:
  pattern: '/admin/config/system/google_analytics'
  defaults:
    _form: 'Drupal\google_analytics\Google_AnalyticsSettingsForm'

to:

google_analytics_settings:
  pattern: '/admin/config/system/google_analytics'
  defaults:
    _form: 'Drupal\google_analytics\GoogleAnalyticsSettingsForm'

Also needed to change filename from:
lib\Drupal\google_analytics\Google_AnalyticsSettingsForm.php

to:
lib\Drupal\google_analytics\GoogleAnalyticsSettingsForm.php

and removed underscore from class name:

<?php
/**
 * Configure Google_Analytics settings for this site.
 */
class Google_AnalyticsSettingsForm extends SystemConfigFormBase {
?>
<?php
/**
 * Configure Google_Analytics settings for this site.
 */
class GoogleAnalyticsSettingsForm extends SystemConfigFormBase {
?>

I'm not aware that class names cannot contain underscores. What's the reason for this?

tim.plunkett’s picture

Status:Active» Closed (works as designed)
hass’s picture

Thanks for sharing this. The error message is not helpful. Per docs

Each _ character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR. The _ character has no special meaning in the namespace.

The error message does not show this. Can we fix this, please?

tim.plunkett’s picture

You can file an issue against https://github.com/symfony/symfony, but this is a PSR-0, not a Drupal or even Symfony thing.
I'm not sure that every time it can't find a service, it should check to see if its a class, check to see if that class has an underscore, and ask if you have actually read the PSR-0 docs before.

hass’s picture

Title:Symfony ServiceNotFoundException: You have requested a non-existent service» Misleading error message: Symfony ServiceNotFoundException: You have requested a non-existent service
Status:Closed (works as designed)» Active

Reopen to get the false error message fixed.

hass’s picture

Category:bug» support
Status:Active» Fixed
Stof’s picture

Status:Fixed» Active

This is not a Symfony issue. The issue comes from the way the DrupalFormController works.

As you can see in http://drupalcode.org/project/drupal.git/blob/d4fba77fdb4b01acb75108c626... it will try to load the class, and then assume that it is a service id if the class does not exist.
As far as Symfony is concerned, the error message is right: there is no service with this id. the container has no way to know that the calling code was expecting "a class name or a service id" and so cannot give an error message in consequence. The only place where a better error message can be given is in the Drupal controller where you know about the 2 possible meanings of the value.

Stof’s picture

and to be clear about underscores in PSR-0, class names can contain underscores. but the path to the file needs to be adjusted.

Drupal\google_analytics\Google_AnalyticsSettingsForm would have to be stored in lib/Drupal/google_analytics/Google/AnalyticsSettingsForm.php instead of lib/Drupal/google_analytics/Google_AnalyticsSettingsForm.php

hass’s picture

Category:support» bug
Crell’s picture

If anything, what we'd do here is catch the (accurate) exception Symfony throws and wrap it in our own, more context-aware exception.

Although if the problem is really just underscores in a class name, the answer is just "learn how PSR-0 works".

Berdir’s picture

Yes, we should either catch the exception and display something useful or just never even attempt to get a service that contains \ and bail out early if we have such a string but don't find the class.

Berdir’s picture

Issue summary:View changes

A

dawehner’s picture

Issue summary:View changes
Status:Active» Fixed

We use the class resolver now, which would have made the following exception:

        throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $definition));

Status:Fixed» Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.