Go多协程并发环境下的错误处理

package main

import (
    "fmt"
    "sync"
)

// 并发调用服务,每个handler都会传入一个调用逻辑函数
func GoroutineNotPanic(handlers ...func() error) (err error) {

    var wg sync.WaitGroup
    // 假设我们要调用handlers这么多个服务
    for _, f := range handlers {

        wg.Add(1)
        // 每个函数启动一个协程
        go func(handler func() error) {

            defer func() {
                // 每个协程内部使用recover捕获可能在调用逻辑中发生的panic
                if e := recover(); e != nil {
                    // 某个服务调用协程报错,可以在这里打印一些错误日志
                }
                wg.Done()
            }()

            // 取第一个报错的handler调用逻辑,并最终向外返回
            e := handler()
            if err == nil && e != nil {
                err = e
            }
        }(f)
    }

    wg.Wait()

    return
}

// 调用示例
func main() {

    // 调用逻辑1
    aRpc := func() error {
        panic("rpc logic A panic")
    }

    // 调用逻辑2
    bRpc := func() error {
        fmt.Println("rpc logic B")
        return nil
    }

    err := GoroutineNotPanic(aRpc, bRpc)
    if err != nil {
        fmt.Println(err)
    }
}