邮件发送失败需通过日志定位:1. 配置 mail.driver=log 并设 log_level=debug 记录原始内容;2. 为 swiftmailer 注入 arraylogger 或 try-catch 捕获 smtp 异常;3. 使用 queue:work --verbose --tries=1、queue:failed 等命令排查队列问题。

邮件发送失败时,Laravel 默认不会直接报错(尤其在队列中),而是静默丢弃异常。要定位问题,关键不是“猜”,而是让日志说话:既要看到 Mail 组件的原始请求与响应,也要确认队列是否真正执行、是否抛出异常。
开启 Laravel 的 Mail 日志(记录原始邮件内容)
Laravel 本身不自带 Mail 详细日志,但可通过配置 log driver 拦截所有发出的邮件(含收件人、主题、HTML/Text 内容),适合开发和调试阶段:
- 修改
config/mail.php,将'driver' => 'log'(注意不是smtp或sendmail) - 确保
LOG_LEVEL=debug在.env中已设置(否则 debug 级日志不写入) - 发送邮件后,查看
storage/logs/laravel.log,会看到类似[2024-05-10 14:22:03] local.DEBUG: MAIL LOG: To: user@example.com, Subject: 验证邮件, Body: <h1>Hello</h1>...
⚠️ 注意:log driver 不真发邮件,仅记录;上线前务必切回真实驱动(如 smtp)。
捕获 SMTP 实际通信错误(启用 SwiftMailer 原生日志)
若用 SMTP(如 Gmail、Mailgun、腾讯企业邮箱),失败常因认证、端口、TLS 设置错误。Laravel 默认不暴露底层 SwiftMailer 错误,需手动注入日志器:
- 在
App\Providers\AppServiceProvider@boot()中添加:
use Illuminate\Support\Facades\Mail;
use Swift_Plugins_Loggers_ArrayLogger;
if (app()->environment('local')) {
$transport = Mail::getSwiftMailer()->getTransport();
$logger = new ArrayLogger();
$transport->setLogger($logger);
// 后续可 dump($logger->dump()) 查看完整 SMTP 交互
}
或更实用的做法:在邮件发送处临时加 try-catch,打印 Swift 异常:
try {
Mail::to('test@example.com')->send(new WelcomeMail());
} catch (\Exception $e) {
\Log::error('Mail send failed: ' . $e->getMessage());
\Log::error('SMTP trace: ' . $e->getTraceAsString());
}
排查队列中的邮件任务(失败不报、重试无提示)
使用 php artisan queue:work 发送邮件时,常见问题有:队列未启动、任务被跳过、异常被吞、重试耗尽后消失。必须主动监控:
- 运行
php artisan queue:work --verbose --tries=1:强制只试 1 次 + 显示完整错误栈 - 检查失败任务表:
php artisan queue:failed,再用php artisan queue:failed-show {id}查看具体异常 - 确保
config/queue.php中'failed' => ['database' => 'mysql']已配置并迁移(php artisan queue:failed-table && php artisan migrate) - 在 Mailable 类的
build()方法开头加\Log::info('Mailable building...');,确认是否走到这一步
快速验证配置是否生效(绕过业务逻辑)
别等用户反馈,用 Artisan 命令直连测试:
- 创建测试命令:
php artisan make:command TestMail,在handle()中写:
Mail::raw('Test from CLI', function ($message) {
$message->to('your-test@email.com')
->subject('Laravel Mail Test');
});
然后运行:php artisan test:mail(或加 --queue 测试队列路径)。成功则说明基础配置通;失败则按上述三步逐层查。











