Problem/Motivation
From #2281691: User interface for migration-based upgrades. Much of the exception handling in the Migrate UI is problematic, including:
- Throwing or catching
\Exception
instead of something more specific. - Very long try/catch blocks for unclear purpose.
- Catching exceptions without reporting what they were or why.
- Possibly relying on exceptions for normal/expected validation code flow?
Much has happened to the code since this original review, and the once large form is now split into several forms. See #2918761: Break up MigrateUpgradeForm into smaller forms and #2682585: Rename MigrationCreationTrait as it no longer creates migrations - it configures them. Each of the six points includes a new note stating where the relevant piece of code now resides. Of the original 6 points, 2 are no longer relevant.
The following points are from reviews on #2281691: User interface for migration-based upgrades:
-
This is now in CredentialForm.php, it is no longer a massive try block.
+++ b/core/modules/drupal_upgrade/src/Form/MigrateUpgradeForm.php @@ -0,0 +1,1196 @@ + try { + ... + catch (\Exception $e) {
This is a MASSIVE try block. Which calls are we catching exceptions for? Why can't they be individually wrapped with classed exceptions?
Also there is a blank line. -
This is now in CredentialForm.php, part of the try block associated with #6.
+++ b/core/modules/migrate_drupal/src/MigrationCreationTrait.php @@ -0,0 +1,205 @@ + catch (\Exception $e) { ... + throw new \Exception('Source database does not contain a recognizable Drupal version.');
Is there a classed exception to catch or throw instead? Using \Exception is not as ideal
-
This is now in MigrationConfigurationTrait.php
+++ b/core/modules/migrate_drupal/src/MigrationCreationTrait.php @@ -0,0 +1,222 @@ + catch (\Exception $e) { + // The table might not exist for example in tests. + }
I think @tim.plunkett mentioned this too, but this is way too broad a
catch
. We should have a followup issue to fix this because it is just swallowing any error. If there is a specific exception that is happening then we should handle it more directly or look at underlying causes. -
This looks fixed. This is now in MigrationConfigurationTrait.php and the PluginNotFoundException was removed (somewhere) from the getMigrations method.
+++ b/core/modules/migrate_drupal/src/MigrationCreationTrait.php @@ -0,0 +1,222 @@ + // Migrations which are not applicable given the source and destination + // site configurations (e.g., what modules are enabled) will be silently + // ignored. + catch (RequirementsException $e) { + } + catch (PluginNotFoundException $e) { + }
This seems a fragile way to handle this; is this related to the existing followup about detecting applicable migrations?
-
This is now in MigrationConfigurationTrait.php and can be fixed in this issue.
+++ b/core/modules/migrate_drupal/src/MigrationCreationTrait.php @@ -0,0 +1,222 @@ + catch (\PDOException $e) { + $version_string = FALSE; + }
We are doing this
catch
if the system table exists, but not if the key_value table exists. -
This is now in CredentialForm.php
+++ b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php @@ -0,0 +1,1227 @@ + catch (\Exception $e) { + $error_message = [ + '#type' => 'inline_template', + '#template' => '{% trans %}Resolve the issue below to continue the upgrade.{% endtrans%}{{ errors }}', + '#context' => [ + 'errors' => [ + '#theme' => 'item_list', + '#items' => [$e->getMessage()], + ], + ], + ];
Also (again),
\Exception
is way generic, and using a try/catch like this to handle expected validation code flow is problematic.
Proposed resolution
Evaluate the types of exceptions used, the reasons they are being caught, the use of try/catch for code flow, and the potential loss/hiding of debug information.
- No longer relevant.
- Reworked that section of code.
- Changed to a PDOException in this patch
- No longer relevant. Fixed elsewhere
- Accessing the key_value tables is change to a try/catch in this patch
- Changed from catching Exception to catching DatabaseException in this patch
Remaining tasks
TBD
User interface changes
N/A
API changes
TBD
Data model changes
TBD