Go协程池错误处理核心是不逃逸panic、统一收集响应:用带缓冲error channel汇总worker recover的panic和任务返回error,主协程监听处理;结合context控制超时取消;按类型频率分级响应熔断告警。
Go 语言本身不支持协程(goroutine)级别的“异常捕获”(如 try/catch),goroutine 中 panic 若未被 recover,会导致整个程序崩溃。因此,在协程池中集中处理错误,核心思路是:**不让错误逃逸出 goroutine,统一收集、转发、响应**。
用 channel 汇总错误
协程池中每个任务应自行 recover panic,并将错误通过专用的 error channel 发送给主协程。主协程监听该 channel,做统一日志、告警或降级处理。
- 定义一个带缓冲的 error channel(容量建议 ≥ 最大并发数,避免阻塞 worker)
- 每个 worker 执行任务前 defer recover,捕获 panic 后转为 error 发送到 channel
- 主协程用 select 或 for-range 监听 error channel,避免阻塞等待
任务函数返回 error 而非 panic
优先让业务逻辑主动返回 error,而非依赖 panic。协程池调度器应检查任务函数的返回值,把非 nil error 推入错误通道。
- 定义任务接口如 type Task func() er
ror,比 func() 更利于错误传递 - 调度器执行完 task() 后判断 err != nil,立即发送到 error channel
- 对可能 panic 的第三方调用(如 JSON 解析、反射操作),在 task 内部加一层 defer recover 封装
协程池自身需支持取消与超时
错误集中处理不只是“收错”,更要控制错误扩散范围。通过 context 控制任务生命周期,可提前终止异常蔓延:
- 为每个任务传入带 timeout 或 cancel 的 context.Context
- worker 在执行中定期 select ctx.Done(),收到信号后主动退出并上报 “context canceled” 错误
- 协程池 shutdown 时,统一 cancel context,触发所有活跃任务安全退出
错误聚合与分级响应
集中接收错误后,不应简单打印就结束。可根据错误类型、频率、来源做轻重分离:
- 用 map[string]int 统计错误码出现次数,超过阈值触发熔断或告警
- 区分 transient error(如网络超时)和 fatal error(如配置加载失败),前者可重试,后者需立即停止池
- 将错误结构体增强为 {TaskID, Timestamp, StackTrace, Cause},便于追踪定位

ror,比 func() 更利于错误传递






