Problem/Motivation
symfony_mailer uses the Symfony\Component\Mime\Address class to create an Address object. This component can't have NULL as an email value, only Strings are allowed. This Symfony Address is constructed from the Symfony_mailer Address class in Address->getSymfony() method.
A NULL value will result in the following error: TypeError: Symfony\Component\Mime\Address::__construct(): Argument #1 ($address) must be of type string, null given, called in /var/www/site/htdocs/modules/contrib/symfony_mailer/src/Address.php
I found out about this bug running drush cim using the role_test_accounts module which creates accounts with no email set (thus null). The core User module sends an email postSave in its User entity object where it notifies the user. Also when deleting (and notifying) a user with no email set will cause this error.
Full error log for role_test_accounts using drush cim:
#1 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Address.php(142): Drupal\symfony_mailer\Address::create(Object(Drupal\user\Entity\User))
#2 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/BaseEmailTrait.php(62): Drupal\symfony_mailer\Address::convert(Array)
#3 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/BaseEmailTrait.php(98): Drupal\symfony_mailer\Email->setAddress('To', Object(Drupal\user\Entity\User))
#4 /var/www/html/htdocs/modules/contrib/symfony_mailer/modules/symfony_mailer_bc/src/Plugin/EmailBuilder/UserEmailBuilder.php(69): Drupal\symfony_mailer\Email->setTo(Object(Drupal\user\Entity\User))
#5 [internal function]: Drupal\symfony_mailer_bc\Plugin\EmailBuilder\UserEmailBuilder->build(Object(Drupal\symfony_mailer\Email))
#6 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Email.php(460): call_user_func(Array, Object(Drupal\symfony_mailer\Email))
#7 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Mailer.php(164): Drupal\symfony_mailer\Email->process()
#8 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Mailer.php(139): Drupal\symfony_mailer\Mailer->doSend(Object(Drupal\symfony_mailer\Email))
#9 /var/www/html/htdocs/core/lib/Drupal/Core/Render/Renderer.php(564): Drupal\symfony_mailer\Mailer->Drupal\symfony_mailer\{closure}()
#10 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Mailer.php(148): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#11 /var/www/html/htdocs/modules/contrib/symfony_mailer/src/Email.php(278): Drupal\symfony_mailer\Mailer->send(Object(Drupal\symfony_mailer\Email))
#12 /var/www/html/htdocs/modules/contrib/symfony_mailer/modules/symfony_mailer_bc/src/MailManagerReplacement.php(97): Drupal\symfony_mailer\Email->send()
#13 /var/www/html/htdocs/core/modules/user/user.module(1071): Drupal\symfony_mailer_bc\MailManagerReplacement->mail('user', 'status_activate...', NULL, 'en', Array, 'no-reply@examp...')
#14 /var/www/html/htdocs/core/modules/user/src/Entity/User.php(139): _user_mail_notify('status_activate...', Object(Drupal\user\Entity\User))
#15 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/EntityStorageBase.php(597): Drupal\user\Entity\User->postSave(Object(Drupal\user\UserStorage), true)
#16 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php(784): Drupal\Core\Entity\EntityStorageBase->doPostSave(Object(Drupal\user\Entity\User), true)
#17 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/EntityStorageBase.php(523): Drupal\Core\Entity\ContentEntityStorageBase->doPostSave(Object(Drupal\user\Entity\User), true)
#18 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php(802): Drupal\Core\Entity\EntityStorageBase->save(Object(Drupal\user\Entity\User))
#19 /var/www/html/htdocs/core/lib/Drupal/Core/Entity/EntityBase.php(339): Drupal\Core\Entity\Sql\SqlContentEntityStorage->save(Object(Drupal\user\Entity\User))
#20 /var/www/html/htdocs/modules/contrib/role_test_accounts/src/RoleTestAccountsManager.php(72): Drupal\Core\Entity\EntityBase->save()
#21 /var/www/html/htdocs/modules/contrib/role_test_accounts/src/RoleTestAccountsManager.php(114): Drupal\role_test_accounts\RoleTestAccountsManager->createTestAccount('test_admin')
#22 /var/www/html/htdocs/modules/contrib/role_test_accounts/src/EventSubscriber/RoleTestAccountsSettingsSubscriber.php(44): Drupal\role_test_accounts\RoleTestAccountsManager->generateRoleTestAccounts(Object(Drupal\Core\Config\Config))
#23 [internal function]: Drupal\role_test_accounts\EventSubscriber\RoleTestAccountsSettingsSubscriber->onSave(Object(Drupal\Core\Config\ConfigCrudEvent), 'config.save', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#24 /var/www/html/htdocs/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(142): call_user_func(Array, Object(Drupal\Core\Config\ConfigCrudEvent), 'config.save', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#25 /var/www/html/htdocs/core/lib/Drupal/Core/Config/Config.php(229): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Drupal\Core\Config\ConfigCrudEvent), 'config.save')
#26 /var/www/html/htdocs/core/lib/Drupal/Core/Config/ConfigImporter.php(943): Drupal\Core\Config\Config->save()
#27 /var/www/html/htdocs/core/lib/Drupal/Core/Config/ConfigImporter.php(787): Drupal\Core\Config\ConfigImporter->importConfig('', 'update', 'role_test_accou...')
#28 /var/www/html/htdocs/core/lib/Drupal/Core/Config/ConfigImporter.php(605): Drupal\Core\Config\ConfigImporter->processConfiguration('', 'update', 'role_test_accou...')
#29 /var/www/html/htdocs/core/lib/Drupal/Core/Config/ConfigImporter.php(509): Drupal\Core\Config\ConfigImporter->processConfigurations(Array)
#30 /var/www/html/vendor/drush/drush/src/Drupal/Commands/config/ConfigImportCommands.php(336): Drupal\Core\Config\ConfigImporter->doSyncStep('processConfigur...', Array)
#31 /var/www/html/vendor/drush/drush/includes/drush.inc(206): Drush\Drupal\Commands\config\ConfigImportCommands->doImport(Object(Drupal\Core\Config\StorageComparer))
#32 /var/www/html/vendor/drush/drush/includes/drush.inc(197): drush_call_user_func_array(Array, Array)
#33 /var/www/html/vendor/drush/drush/src/Drupal/Commands/config/ConfigImportCommands.php(307): drush_op(Array, Object(Drupal\Core\Config\StorageComparer))
#34 [internal function]: Drush\Drupal\Commands\config\ConfigImportCommands->import(NULL, Array)
#35 /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(257): call_user_func_array(Array, Array)
#36 /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(212): Consolidation\AnnotatedCommand\CommandProcessor->runCommandCallback(Array, Object(Consolidation\AnnotatedCommand\CommandData))
#37 /var/www/html/vendor/consolidation/annotated-command/src/CommandProcessor.php(176): Consolidation\AnnotatedCommand\CommandProcessor->validateRunAndAlter(Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#38 /var/www/html/vendor/consolidation/annotated-command/src/AnnotatedCommand.php(311): Consolidation\AnnotatedCommand\CommandProcessor->process(Object(Symfony\Component\Console\Output\ConsoleOutput), Array, Array, Object(Consolidation\AnnotatedCommand\CommandData))
#39 /var/www/html/vendor/symfony/console/Command/Command.php(255): Consolidation\AnnotatedCommand\AnnotatedCommand->execute(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#40 /var/www/html/vendor/symfony/console/Application.php(1027): Symfony\Component\Console\Command\Command->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#41 /var/www/html/vendor/symfony/console/Application.php(273): Symfony\Component\Console\Application->doRunCommand(Object(Consolidation\AnnotatedCommand\AnnotatedCommand), Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#42 /var/www/html/vendor/symfony/console/Application.php(149): Symfony\Component\Console\Application->doRun(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#43 /var/www/html/vendor/drush/drush/src/Runtime/Runtime.php(118): Symfony\Component\Console\Application->run(Object(Drush\Symfony\DrushArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#44 /var/www/html/vendor/drush/drush/src/Runtime/Runtime.php(48): Drush\Runtime\Runtime->doRun(Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#45 /var/www/html/vendor/drush/drush/drush.php(72): Drush\Runtime\Runtime->run(Array)
#46 /var/www/html/vendor/drush/drush/drush(4): require('/var/www/html/v...')
#47 /var/www/html/vendor/bin/drush(120): include('/var/www/html/v...')
#48 {main}.Steps to reproduce
*DELETE USER AND NOTIFY*
- Enable symfony_mailer and its BC sub-module.
- Create a user with no email set. Delete and notify the user.
- The mail should fail and cause the error above because no email is set.
*ROLE_TEST_ACCOUNTS*
- Enable symfony_mailer and its BC sub-module.
- Enable role_test_accounts
- Configure role_test_accounts to create specific users with no email set
- Alter and/or delete some generated accounts
- Run drush cim
role_test_accounts should call a postSave on the user entity which will cause these errors.
Proposed resolution
Convert NULL values to empty strings in the symfony_mailer Address constructor. See patch
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | symfony_mailer-3305696-9.patch | 737 bytes | v.hilkov |
| #8 | symfony_mailer-3305696-8.patch | 530 bytes | stijnstroobants |
| #2 | symfony_mailer-address_null_check-3305696-1.patch | 720 bytes | daneduijnkerke |
Issue fork symfony_mailer-3305696
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:
Comments
Comment #2
daneduijnkerke commentedPatch added.
Comment #3
daneduijnkerke commentedComment #4
daneduijnkerke commentedComment #5
ronald van belzen commentedMaybe the following would be better, instead of the if-statement:
Comment #6
adamps commentedThanks for the report and patch.
The issue is about notifying a user with no email. We should check what Core does and copy that. The proposed solution is that when silently ignore the problem. Another possibility would be to raise an error report.
I propose we leave the code in Address - it's correct that the email field is mandatory for this class. I would fix instead in
UserEmailBuilder::build(). If the user has no address, then throw a SkipMailException.Comment #7
nojj commentedI am having a very similar error, when creating a new user account from backend without email address.
eher massage is:
TypeError: Argument 1 passed to Drupal\symfony_mailer\Address::__construct() must be of the type string, null given, called in /var/www/html/web/modules/contrib/symfony_mailer/src/Address.php on line 83 in Drupal\symfony_mailer\Address->__construct() (Zeile 58 in /var/www/html/web/modules/contrib/symfony_mailer/src/Address.php)
is this fixed in a later release ?
i testet latest beta 1.1.0 bata3 and the issue still exits.
Comment #8
stijnstroobantsAs mentioned above this is not the best solution, but created a patch for 1.6.x
Comment #9
v.hilkov commentedLast patch didn't worked, I made $email in __construct() nullable
Comment #10
adamps commentedThe code in
_user_mail_notify()generates a log and skips sending, so we should do that here.Comment #11
adamps commentedComment #13
adamps commentedThis was fixed in Core by #3518058: _user_mail_notify() doesn't handle accounts without an email address. It could still be hit by calling UserMailer directly. Seeing as I have just written the code, I might as well commit it to cover this case.
Comment #15
adamps commented