Problem/Motivation

AlreadyInstalledException is thrown from four different places and produces the same output on each, so you can't know precisely why the installation process (perhaps mistakenly) believes Drupal is already installed. See https://github.com/drush-ops/drush/issues/511 for one false positive scenario.

Proposed resolution

Add a $detail string argument to AlreadyInstalledException::__construct() and incorporate it into the output. Provide useful info when throwing the exception.

Remaining tasks

Bikeshed the info to provide.

User interface changes

@todo -- new exception messages in various specific already-installed scenarios.

API changes

@todo

  • New InstallerException child classes for specific error conditions.
  • Additional argument to AlreadyInstalledException.
CommentFileSizeAuthor
#51 2459671.44_51.rawdiff.txt6.28 KBdww
#51 2459671-51.do-not-test.patch8.05 KBdww
#44 2459671.39_44.rawdiff.txt3.19 KBdww
#44 2459671-44.9_1_x.patch8.33 KBdww
#39 interdiff-2459671-37-39.txt2.39 KByogeshmpawar
#39 2459671-39.patch8.04 KByogeshmpawar
#37 add-details-installer-2459671-37.patch9.56 KBgrahl
#36 add-details-installer-2459671-36.patch9.47 KBgrahl
#35 add-details-installer-2459671-35.patch6.74 KBgrahl
#22 interdiff.txt1.53 KBPieterJanPut
#21 add_detail_to-2459671-21.patch8.59 KBPieterJanPut
#18 add_detail_to-2459671-18.patch8.39 KBborisson_
#18 interdiff.txt3.53 KBborisson_
#15 add_detail_to-2459671-15.patch8.18 KBborisson_
#15 interdiff.txt4.43 KBborisson_
#13 add_detail_to-2459671-13.patch8.24 KBborisson_
#13 interdiff.txt5.14 KBborisson_
#11 add_detail_to-2459671-11.patch8.13 KBborisson_
#11 interdiff.txt3.2 KBborisson_
#9 add_detail_to-2459671-9.patch8.01 KBborisson_
#9 interdiff.txt8.34 KBborisson_
#9 Screen Shot 2015-08-03 at 18.05.24.png115.06 KBborisson_
#6 add_detail_to-2459671-6.patch3.49 KBbzrudi71
#3 add_detail_to-2459671-3.patch3.49 KBmikeryan
#1 add_detail_to-2459671-1.patch3.26 KBmikeryan
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mikeryan’s picture

Status: Active » Needs review
FileSize
3.26 KB

Patch attached - running through the testbot, but should go back to "Needs work" regardless, need to refine the messages.

dawehner’s picture

Adding more details to exceptions is always a good idea!

  1. +++ b/core/includes/install.core.inc
    @@ -1045,7 +1047,8 @@ function install_verify_completed_task() {
       if (isset($task)) {
         if ($task == 'done') {
    -      throw new AlreadyInstalledException(\Drupal::service('string_translation'));
    +      throw new AlreadyInstalledException(\Drupal::service('string_translation'),
    +        "I don't know why this is an exception.");
         }
    

    I think the point is that we should not verify tasks again, once we have completed the test. Maybe throw something like: 'Installation already finished'?

  2. +++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
    @@ -19,13 +19,18 @@ class AlreadyInstalledException extends InstallerException {
    +      $message .= $this->t("<li>$detail</li>\n");
    

    If we really want to translate those messages, we have to translate them directly in the beginning so that potx can scan them.

mikeryan’s picture

FileSize
3.49 KB

With the requested changes (resisting the technically out-of-scope temptation to remove the null-op $task = NULL line)...

amateescu’s picture

Category: Feature request » Task
Priority: Minor » Normal
Status: Needs review » Reviewed & tested by the community

The patch looks good to me and it also helps with debugging random failures for Postgres/SQLite on DrupalCI.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Let's just use different exceptions here and change AlreadyInstalledException into something abstract.

bzrudi71’s picture

Just re-uploading patch to enable PG-bot testing. Setting to NW again later!

bzrudi71’s picture

Status: Needs review » Needs work

Back to NW...

xjm’s picture

Priority: Normal » Major

#4 seems like a reason for this to be major even.

borisson_’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
115.06 KB
8.34 KB
8.01 KB

Changed the AlreadyInstalledException to be a abstract class, added 4 implementations of that class and throw those instead.

Added a screenshot of what this looks like when Implemented.

amateescu’s picture

+++ b/core/includes/install.core.inc
@@ -488,7 +491,8 @@ function install_begin_request($class_loader, &$install_state) {
+      throw new ActiveConfigurationExists($translator);

@@ -1069,7 +1073,8 @@ function install_verify_completed_task() {
+      throw new InstallationTasksCompleted($translator);

Don't we need the Exception suffix for these two as well?

borisson_’s picture

@amateescu, you're right, fixed in the attached patch.

amateescu’s picture

Ah, I should've caught this sooner:

+++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
@@ -12,7 +12,13 @@
+  protected $specificMessage = '';

@@ -22,16 +28,20 @@ class AlreadyInstalledException extends InstallerException {
+      $message .= $this->t('<li>' . $this->specificMessage . '</li>');

Dynamic strings won't get picked up by the translatable strings extractor so we need to translate the message in the constructor of each exception class. See https://www.drupal.org/developing/api/8/localization ("Variables in user interface text").

borisson_’s picture

amateescu’s picture

  1. +++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
    @@ -15,24 +15,20 @@
    +   *  A specific message set from a class implementing this Exception.
    

    Missing a space at the beginning and maybe we should shorten the comment to just "A specific exception message.", mostly because subclasses are extending this class, they don't implement it.

  2. +++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
    @@ -15,24 +15,20 @@
    +      $message .= $this->t($specific_message);
    

    No need to pass $specific_message through $this->t() anymore, but we still need the wrapping <li>s :P

borisson_’s picture

#14.1: Fixed.
#14.2: I had moved the wrapping <li>'s to the subclasses, but this makes more sense, fixed.

amateescu’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, this looks ready to me.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Core/Installer/Exception/DatabaseAlreadyPopulatedException.php
@@ -0,0 +1,24 @@
+    parent::__construct($string_translation, $this->t('Database is already populated.'));

This will call $this->t() before the $string_translation is set thereby ignoring the passed in service and just reacing into \Drupal as a service locator.

borisson_’s picture

Status: Needs work » Needs review
FileSize
3.53 KB
8.39 KB

The attached patch moves setting stringTranslation to the implementing exceptions.

amateescu’s picture

Status: Needs review » Reviewed & tested by the community

#17: good point!

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

The more I look at this code the more I get weirded out by the use of translated string in exceptions. The installer is the only place this happens in core. And the exception statndards says not to do this. I think we should fix this here.

PieterJanPut’s picture

Status: Needs work » Needs review
FileSize
8.59 KB
PieterJanPut’s picture

FileSize
1.53 KB

Adding interdiff

PieterJanPut’s picture

Forget to remove some, fixed.

Status: Needs review » Needs work

The last submitted patch, 23: add_detail_to-2459671-23.patch, failed testing.

alexpott’s picture

@PieterJanPut we still need the translated message but we should NOT use exceptions to pass translated string around.

What we need to do is continue to introduce the new exceptions here. Add a new class to the installer classes called ConvertInstallerExceptionToMessage() which has the logic for converting an exception to a translated message. And then where the exception is caught use this new utility class to get the translated message for the particular exception.

[edit: corrected incorrect first sentence]

dawehner’s picture

+++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
@@ -12,26 +12,28 @@
+    $title = 'Drupal already installed.';
...
+    $message .= '<li>To start over, you must empty your existing database and copy <em>default.settings.php</em> over <em>settings.php</em>.</li>
+<li>To upgrade an existing installation, proceed to the <a href="' . $GLOBALS['base_path'] . 'update.php">update script</a>.</li>
+<li>View your <a href="' . $GLOBALS['base_url'] . '">existing site</a>.</li>
+</ul>';

Doesn't that break any kind of translatability?

alexpott’s picture

Status: Needs review » Needs work

@dawehner yes it does that's what I was trying to say in #25.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

hansfn’s picture

Assigned: Unassigned » hansfn

I think getting this patch in is worthwhile[1] and will be happy to update it (and make translation work properly).

@alexpott: You wrote 3 years ago (!): "What we need to do is continue to introduce the new exceptions here. Add a new class to the installer classes called ConvertInstallerExceptionToMessage() which has the logic for converting an exception to a translated message."

Looking at the current implementation of AlreadyInstalledException, do you still think ConvertInstallerExceptionToMessage is needed? Isn't it just to introduce the new more specific exceptions (following the current AlreadyInstalledException)?

[1] When helping users struggling with a failed install, a ,more specific exception is very helpful for us doing support. Just spent 10 minutes helping a user on Slack. A frustrating experience for both of us.

grahl’s picture

Version: 8.6.x-dev » 8.7.x-dev
FileSize
6.74 KB

Attached is a reroll for 8.7 with the translation issue not addressed.

grahl’s picture

...and fixing the patch level.

yogeshmpawar’s picture

Assigned: hansfn » yogeshmpawar
yogeshmpawar’s picture

Assigned: yogeshmpawar » Unassigned
FileSize
8.04 KB
2.39 KB

Resolved some coding standard issue & added an interdiff.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.9 was released on November 6 and is the final full bugfix release for the Drupal 8.7.x series. Drupal 8.7.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.8.0 on December 4, 2019. (Drupal 8.8.0-beta1 is available for testing.)

Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

tvb’s picture

Version: 8.8.x-dev » 8.9.x-dev

This would be a useful improvement.

The patch applies cleanly to 8.9.x-dev.

I could create the conditions to throw the various exceptions but adding translations seems not to work.

Status unchanged 'Needs Review'.

1) InstallationTasksCompletedException

After a fresh install revisit install.php.

Result:
Drupal already installed.

Installation tasks have already been completed.
To start over, you must empty your existing database and copy default.settings.php over settings.php.
To upgrade an existing installation, proceed to the update script.
View your existing site.

2) DatabaseAlreadyPopulatedException

Comment out $databases array in settings.php and revisit install.php.

Result:
Drupal already installed.

Database is already populated.
To start over, you must empty your existing database and copy default.settings.php over settings.php.
To upgrade an existing installation, proceed to the update script.
View your existing site.

3) ActiveConfigurationExistsException

Drop table sessions (do not drop config table) and revisit install.php.

Result:
Drupal already installed.

Active configuration already exists.
To start over, you must empty your existing database and copy default.settings.php over settings.php.
To upgrade an existing installation, proceed to the update script.
View your existing site.

Note Drupal Core doesn't create an active config directory anymore and The sync directory is defined in $settings and not $config_directories.

4) SettingsAlreadyExistsException

After a fresh install, change database name to a non-existant database in settings.php and revisit install.php.

Result:
Drupal already installed.

Configured settings.php already exists.
To start over, you must empty your existing database and copy default.settings.php over settings.php.
To upgrade an existing installation, proceed to the update script.
View your existing site.

5) Translation

Enabled module Interface translation, added a language (nl) and added a language path prefix for English.
Cleared cache.

But the new strings never show up at admin/config/regional/translate to add translations.

Is this code or configuration (or both) related? Needs further review.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

grahl’s picture

Status: Needs review » Needs work

Patch no longer applies to 8.9.2 or newer.

dww’s picture

Incomplete re-roll. Something is funky here. The hunk that was to be replaced with throwing SettingsAlreadyExistsException doesn't exist in 9.1.x branch anymore. Nor 9.0.x or 8.9.x. Looks like it was removed in #3120731: Incorrect "Drupal already installed" if any database settings are wrong or unsatisfactory.

So I believe all of core/lib/Drupal/Core/Installer/Exception/SettingsAlreadyExistsException.php is dead code, since we're not throwing it anywhere.

But I don't want to leave it out of the patch (yet), since I haven't taken the time to fully understand this issue and all the gory details. So leaving at NW for sorting this out and cleaning it up.

Interdiff isn't working, so here's a raw diff of #39 vs. this.

Also note that I fixed the @throws annotation on install_verify_database_ready() and the comment where it's called.

There's some other stuff I'd fix in here, but I want to start with as close to a "pure" reroll as possible, before making other changes.

Also, tagging for 'Needs tests', since there's no test coverage of the new exceptions in here, and we certainly want that. ;)

Thanks,
-Derek

p.s. I named this "9_1_x" but I just checked and it applies to 8.9.x and 9.0.x, too... sorry for any potential confusion. Although I doubt this would be backported, so it probably doesn't matter.

dww’s picture

Here ares some of the other things we should change before this is NR:

  1. +++ b/core/includes/install.core.inc
    @@ -525,7 +527,8 @@ function install_begin_request($class_loader, &$install_state) {
    -      throw new AlreadyInstalledException($container->get('string_translation'));
    +      $translator = $container->get('string_translation');
    +      throw new ActiveConfigurationExistsException($translator);
    
    @@ -1127,7 +1130,8 @@ function install_verify_completed_task() {
    -      throw new AlreadyInstalledException(\Drupal::service('string_translation'));
    +      $translator = \Drupal::service('string_translation');
    +      throw new InstallationTasksCompletedException($translator);
    
    @@ -1177,7 +1181,8 @@ function install_verify_database_ready() {
    -    throw new AlreadyInstalledException(\Drupal::service('string_translation'));
    +    $translator = \Drupal::service('string_translation');
    +    throw new DatabaseAlreadyPopulatedException($translator);
    

    Don't understand this pattern with the new $translator local variables. Why not:

    throw new WhateverItShouldBeException($container->get('string_translation'));
    

    basically as before?

  2. +++ b/core/lib/Drupal/Core/Installer/Exception/ActiveConfigurationExistsException.php
    @@ -0,0 +1,20 @@
    + * Exception thrown if Drupal is installed already.
    
    +++ b/core/lib/Drupal/Core/Installer/Exception/DatabaseAlreadyPopulatedException.php
    @@ -0,0 +1,20 @@
    + * Exception thrown if Drupal is installed already.
    
    +++ b/core/lib/Drupal/Core/Installer/Exception/InstallationTasksCompletedException.php
    @@ -0,0 +1,20 @@
    + * Exception thrown if Drupal is installed already.
    
    +++ b/core/lib/Drupal/Core/Installer/Exception/SettingsAlreadyExistsException.php
    @@ -0,0 +1,20 @@
    + * Exception thrown if Drupal is installed already.
    

    All of these comments should be more specific for the separate exception types.

  3. +++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
    @@ -7,26 +7,28 @@
    +   * @var string $specific_message
    

    s/@var/@param

  4. +++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
    @@ -7,26 +7,28 @@
    +   *   A specific message exception message.
    

    This message needs message help (message). 😉

    Maybe:

    (Optional) A specific message to include when the exception is thrown.

    ?

    Guess it should also mention that this custom message is prepended to the main text that's always printed...

  5. +++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
    @@ -7,26 +7,28 @@
    -    $this->stringTranslation = $string_translation;
    

    Don't we still need this line?

    Although, why are we passing the TranslationInterface at all? Doesn't look like it's used. Maybe the better fix is to remove it everywhere?

  6. +++ b/core/lib/Drupal/Core/Installer/Exception/SettingsAlreadyExistsException.php
    @@ -0,0 +1,20 @@
    +class SettingsAlreadyExistsException extends AlreadyInstalledException {
    

    Per #44, I believe this is all dead code now. TBD.

  7. +++ b/core/lib/Drupal/Core/Installer/Exception/SettingsAlreadyExistsException.php
    @@ -0,0 +1,20 @@
     
    

    Patch ends before any tests are added. ;) #NeedsTests.

Thanks,
-Derek

dww’s picture

Issue summary: View changes
Issue tags: +Needs followup

Re: #45.5b: Looks like we should have a follow-up to remove (deprecate?) StringTranslationTrait from InstallerException since we don't want to translate exception titles or messages anymore. Quick search doesn't turn up anything, but maybe someone else knows if it already exists.

andypost’s picture

I think we have sniffer now to prevent translation of exceptions starting from 8.9 #2055851: Remove translation of exception messages

dww’s picture

Right. So is this the issue to deprecate StringTranslationTrait from InstallerException, or should we do that separately (probably first), and then this patch will be smaller and simpler?

andypost’s picture

++ file blocker for the issue and postpone that one

dww’s picture

Title: Add detail to AlreadyInstalledException » [PP-1] Add detail to AlreadyInstalledException
Status: Needs work » Postponed
Related issues: +#3161140: Remove the StringTranslationTrait from InstallerException
dww’s picture

FileSize
8.05 KB
6.28 KB

Assuming that lands, something like this.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.