Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email Notification Customizing The Recipient Bug in Laravel9 #40895

Closed
karimnaimy opened this issue Feb 9, 2022 · 8 comments · Fixed by #40921
Closed

Email Notification Customizing The Recipient Bug in Laravel9 #40895

karimnaimy opened this issue Feb 9, 2022 · 8 comments · Fixed by #40921
Labels

Comments

@karimnaimy
Copy link

karimnaimy commented Feb 9, 2022

  • Laravel Version: 9.0
  • PHP Version: 8.1
  • Database Driver & Version: MySQL

Description:

When the email address and name are returned from routeNotificationForMail in a modal, the RfcComplianceException is thrown.

public function routeNotificationForMail($notification)  
{  
        \Log::debug([$this->email => $this->name]);  
        return [$this->email => $this->name];
}

image

Log

[2022-02-09 16:48:36] local.DEBUG: array (
  'karim.naimy@gmail.com' => 'karim',
)  
[2022-02-09 16:48:36] local.DEBUG: array (
  'karim.naimy@gmail.com' => 'karim',
)  
[2022-02-09 16:48:36] local.ERROR: Email "karim" does not comply with addr-spec of RFC 2822. {"exception":"[object] (Symfony\\Component\\Mime\\Exception\\RfcComplianceException(code: 0): Email \"karim\" does not comply with addr-spec of RFC 2822. at /home/karim/www/example-app/vendor/symfony/mime/Address.php:54)
[stacktrace]
#0 /home/karim/www/example-app/vendor/symfony/mime/Address.php(96): Symfony\\Component\\Mime\\Address->__construct()
#1 /home/karim/www/example-app/vendor/symfony/mime/Address.php(115): Symfony\\Component\\Mime\\Address::create()
#2 /home/karim/www/example-app/vendor/symfony/mime/Email.php(528): Symfony\\Component\\Mime\\Address::createArray()
#3 /home/karim/www/example-app/vendor/symfony/mime/Email.php(169): Symfony\\Component\\Mime\\Email->setListAddressHeaderBody()
#4 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Mail/Message.php(211): Symfony\\Component\\Mime\\Email->to()
#5 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Mail/Message.php(105): Illuminate\\Mail\\Message->addAddresses()
#6 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(163): Illuminate\\Mail\\Message->to()
#7 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(135): Illuminate\\Notifications\\Channels\\MailChannel->addressMessage()
#8 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(80): Illuminate\\Notifications\\Channels\\MailChannel->buildMessage()
#9 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php(267): Illuminate\\Notifications\\Channels\\MailChannel->Illuminate\\Notifications\\Channels\\{closure}()
#10 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(65): Illuminate\\Mail\\Mailer->send()
#11 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(148): Illuminate\\Notifications\\Channels\\MailChannel->send()
#12 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(106): Illuminate\\Notifications\\NotificationSender->sendToNotifiable()
#13 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Support/Traits/Localizable.php(19): Illuminate\\Notifications\\NotificationSender->Illuminate\\Notifications\\{closure}()
#14 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(109): Illuminate\\Notifications\\NotificationSender->withLocale()
#15 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(79): Illuminate\\Notifications\\NotificationSender->sendNow()
#16 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php(39): Illuminate\\Notifications\\NotificationSender->send()
#17 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php(18): Illuminate\\Notifications\\ChannelManager->send()
#18 /home/karim/www/example-app/vendor/laravel/framework/src/Illuminate/Auth/Passwords/CanResetPassword.php(27): App\\Models\\User->notify()
......
#70 {main}
"} 

Steps To Reproduce:

@karimnaimy karimnaimy changed the title Email Notification Customizing The Recipient Email Notification Customizing The Recipient Bug in Laravel9 Feb 10, 2022
@driesvints driesvints added the bug label Feb 10, 2022
@karimnaimy
Copy link
Author

Changing the return value of routeNotificationForMail function in the modal to match the FROM_STRING_PATTERN regex in Symfony\Component\Mime\Address is working as expected.

// Symfony\Component\Mime\Address
private const FROM_STRING_PATTERN = '~(?<displayName>[^<]*)<(?<addrSpec>.*)>[^>]*~'; 
//User Modal
public function routeNotificationForMail($notification)  
{  
  return "$this->name <$this->email>";  
}

@driesvints
Copy link
Member

Thanks for reporting. I've sent in a fix for this: #40921

@jordanade
Copy link

jordanade commented Mar 31, 2022

Relatedly, in Laravel v9.5.1 I got a TypeError: "Illuminate\Mail\Message::Illuminate\Mail\{closure}(): Argument #1 ($address) must be of type array|string, null given" apparently because my $user->name was null (code simplified):

class User extends Authenticatable
{
    use Notifiable;

    public function routeNotificationForMail($notification)
    {
        return [$this->email => $this->name];
    }
}

@driesvints
Copy link
Member

@jordanade i think that just surfaces a bug in your code. If the name is null then you should just return the email address.

@jordanade
Copy link

jordanade commented Apr 1, 2022

@driesvints Nevertheless, an undocumented breaking change in Laravel 9 for a common situation that arises from boilerplate code (in fact right from the docs). Currently ungoogleable so I'm sure me posting the error message above will help others.

@driesvints
Copy link
Member

@jordanade please post the entire stack trace of your error with the correct call lines.

@jordanade
Copy link

Sure, here is one of them @driesvints

TypeError: Illuminate\Mail\Message::Illuminate\Mail\{closure}(): Argument #1 ($address) must be of type array|string, null given
#88 /vendor/laravel/framework/src/Illuminate/Mail/Message.php(223): Illuminate\Mail\Message::Illuminate\Mail\{closure}
#87 [internal](0): array_map
#86 /vendor/laravel/framework/src/Illuminate/Collections/Collection.php(721): Illuminate\Support\Collection::map
#85 /vendor/laravel/framework/src/Illuminate/Mail/Message.php(233): Illuminate\Mail\Message::addAddresses
#84 /vendor/laravel/framework/src/Illuminate/Mail/Message.php(105): Illuminate\Mail\Message::to
#83 /vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(177): Illuminate\Notifications\Channels\MailChannel::addressMessage
#82 /vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(137): Illuminate\Notifications\Channels\MailChannel::buildMessage
#81 /vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(82): Illuminate\Notifications\Channels\MailChannel::Illuminate\Notifications\Channels\{closure}
#80 /vendor/laravel/framework/src/Illuminate/Mail/Mailer.php(267): Illuminate\Mail\Mailer::send
#79 /vendor/laravel/framework/src/Illuminate/Notifications/Channels/MailChannel.php(67): Illuminate\Notifications\Channels\MailChannel::send
#78 /vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(148): Illuminate\Notifications\NotificationSender::sendToNotifiable
#77 /vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(106): Illuminate\Notifications\NotificationSender::Illuminate\Notifications\{closure}
#76 /vendor/laravel/framework/src/Illuminate/Support/Traits/Localizable.php(19): Illuminate\Notifications\NotificationSender::withLocale
#75 /vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(109): Illuminate\Notifications\NotificationSender::sendNow
#74 /vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php(79): Illuminate\Notifications\NotificationSender::send
#73 /vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php(39): Illuminate\Notifications\ChannelManager::send
#72 /vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php(18): App\User::notify
#71 /app/Listeners/UserEventSubscriber.php(19): App\Listeners\UserEventSubscriber::handleUserAssignedRole
#70 /vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(441): Illuminate\Events\Dispatcher::Illuminate\Events\{closure}
#69 /vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(249): Illuminate\Events\Dispatcher::dispatch
#68 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php(206): Illuminate\Database\Eloquent\Model::fireCustomModelEvent
#67 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php(181): Illuminate\Database\Eloquent\Model::fireModelEvent
#66 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1176): Illuminate\Database\Eloquent\Model::performInsert
#65 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(996): Illuminate\Database\Eloquent\Model::save
#64 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(531): Illuminate\Database\Eloquent\Builder::Illuminate\Database\Eloquent\{closure}
#63 /vendor/laravel/framework/src/Illuminate/Support/helpers.php(302): tap
#62 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(532): Illuminate\Database\Eloquent\Builder::firstOrCreate
#61 /vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(23): Illuminate\Database\Eloquent\Model::forwardCallTo
#60 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2133): Illuminate\Database\Eloquent\Model::__call
#59 /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2145): Illuminate\Database\Eloquent\Model::__callStatic
#58 /app/User.php(76): App\User::assignRole
#57 /app/Site.php(104): App\Site::assignUserWithRole
#56 /app/Http/Controllers/SiteUserController.php(39): App\Http\Controllers\SiteUserController::store
#55 /vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): Illuminate\Routing\Controller::callAction
#54 /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(45): Illuminate\Routing\ControllerDispatcher::dispatch
#53 /vendor/laravel/framework/src/Illuminate/Routing/Route.php(261): Illuminate\Routing\Route::runController
#52 /vendor/laravel/framework/src/Illuminate/Routing/Route.php(204): Illuminate\Routing\Route::run
#51 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(725): Illuminate\Routing\Router::Illuminate\Routing\{closure}
#50 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#49 /app/Http/Middleware/PageRequestInjector.php(33): App\Http\Middleware\PageRequestInjector::handle
#48 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#47 /vendor/spatie/laravel-referer/src/CaptureReferer.php(21): Spatie\Referer\CaptureReferer::handle
#46 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#45 /vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\Routing\Middleware\SubstituteBindings::handle
#44 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#43 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::handle
#42 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#41 /vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\View\Middleware\ShareErrorsFromSession::handle
#40 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#39 /vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Session\Middleware\StartSession::handleStatefulRequest
#38 /vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession::handle
#37 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#36 /vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::handle
#35 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#34 /vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Cookie\Middleware\EncryptCookies::handle
#33 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#32 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline::then
#31 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(727): Illuminate\Routing\Router::runRouteWithinStack
#30 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(702): Illuminate\Routing\Router::runRoute
#29 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(666): Illuminate\Routing\Router::dispatchToRoute
#28 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(655): Illuminate\Routing\Router::dispatch
#27 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(167): Illuminate\Foundation\Http\Kernel::Illuminate\Foundation\Http\{closure}
#26 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#25 /vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestIpMiddleware.php(45): Sentry\Laravel\Http\SetRequestIpMiddleware::handle
#24 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#23 /vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestMiddleware.php(42): Sentry\Laravel\Http\SetRequestMiddleware::handle
#22 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#21 /vendor/livewire/livewire/src/DisableBrowserCache.php(19): Livewire\DisableBrowserCache::handle
#20 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#19 /vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(60): Barryvdh\Debugbar\Middleware\InjectDebugbar::handle
#18 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#17 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Foundation\Http\Middleware\TransformsRequest::handle
#16 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::handle
#15 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#14 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Foundation\Http\Middleware\TransformsRequest::handle
#13 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TrimStrings::handle
#12 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#11 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Foundation\Http\Middleware\ValidatePostSize::handle
#10 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#9 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::handle
#8 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#7 /vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\Http\Middleware\TrustProxies::handle
#6 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#5 /vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Middleware.php(53): Sentry\Laravel\Tracing\Middleware::handle
#4 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Pipeline\Pipeline::Illuminate\Pipeline\{closure}
#3 /vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline::then
#2 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(142): Illuminate\Foundation\Http\Kernel::sendRequestThroughRouter
#1 /vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(111): Illuminate\Foundation\Http\Kernel::handle
#0 /public/index.php(53): null

@driesvints
Copy link
Member

Heya, I tried to provide a fix through #41870. Still, this will not notify you of the fact that no name was provided. It's best that you also add a check in userland.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants