应统一使用 $job->getexception() 获取真实异常,它自动适配各驱动;失败告警需按完整类名映射策略,并用 queue::failing() 全局钩子集中处理,避免 failed() 局部分散;redis 驱动须启用 store_failed_jobs 才能获取异常。

队列任务失败时怎么拿到具体错误类型
关键不是捕获异常,而是从 Illuminate\Queue\Jobs\Job 实例里提取真实异常类名和消息。Laravel 默认只记录日志,failed 方法里拿不到原始异常对象——得靠 getException() 或解析 exception 属性。
-
failed()回调中直接用$exception->getMessage()可能报错,因为有些驱动(如 database)存的是序列化字符串,需先反序列化或调用getException() - 推荐统一用
$job->getException(),它会自动处理 Redis、Database、Sync 等不同驱动的异常还原逻辑 - 注意:若队列配置了
retry_after且任务超时,实际抛出的是Illuminate\Queue\MaxAttemptsExceededException,不是你代码里的原始异常
Laravel 队列失败后如何按错误类型路由到不同告警群
别在 failed() 里硬写 if-else 发消息,应该抽象一层「告警策略映射」。核心是把异常类名(如 App\Exceptions\PaymentFailedException)映射到企业微信/钉钉 webhook 地址或群机器人 token。
- 定义配置项
config/queue_alerts.php,内容为['App\Exceptions\NetworkTimeoutException' => 'webhook_url_a', 'Illuminate\Database\QueryException' => 'webhook_url_b'] - 在
failed()中用get_class($exception)获取完整类名,再向上遍历父类(用class_parents()),匹配最具体的策略 - 避免只匹配末尾类名(如
'QueryException'),否则PDOException和QueryException会撞车
为什么用 Queue::failing() 比重写 failed() 更灵活
Queue::failing() 是全局钩子,在所有任务执行完、无论是否定义了 failed() 方法都会触发;而每个任务类的 failed() 是局部的,改起来分散、难统一管控。
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
- 在
AppServiceProvider::boot()里注册Queue::failing(),能集中做分类、限流、采样(比如每小时只发一次同类型告警) - 如果同时用了 Horizon,它的
failed_jobs表字段有限,exception字段默认只存前 65535 字节,长堆栈会被截断——这时必须依赖Queue::failing()拿到完整异常再处理 - 注意:该钩子不支持异步发送(比如 dispatch 新任务),回调内必须同步完成 HTTP 请求,否则可能因队列进程退出而丢告警
常见踩坑:Redis 驱动下 getException() 返回 null
这不是 bug,是 Redis 驱动默认不存异常对象,只存日志行。除非你显式开启 store_failed_jobs 并设为 true,否则 getException() 必然为空。
- 检查
config/queue.php中对应连接的'options' => ['store_failed_jobs' => true]是否启用(仅 Redis 驱动支持) - Database 驱动默认就存,但要注意
failed_jobs.exception字段类型要是text,不是varchar(255) - 临时调试可用
Log::error('Raw exception: ' . $job->payload()['exception'] ?? 'none')打印原始 payload 内容
异常分类告警真正难的不是发消息,而是怎么稳定还原出原始异常上下文——驱动差异、序列化方式、Horizon 截断、PHP 版本对异常对象序列化的兼容性,这些地方稍微没对齐,告警就会静默失效。










