Go 异常捕获处理: panic(err) 与 recover()

代码实例

func (rcvr *CQL) Compile(ctx context.Context) string {
    defer func() {
        if err := recover(); err != nil {
            //打印调用栈信息
            buf := make([]byte, 2048)
            n := runtime.Stack(buf, false)
            stackInfo := fmt.Sprintf("%s", buf[:n])
            logu.CtxError(ctx, error_code.ProcessError, "Compile", "[FillStructInfo] rcvr=%v, resultRecord=%v, panic recovered: \n%v\n%v", convert.ToJSONString(rcvr), err, stackInfo)
        }
    }()

    return rcvr.compile1()
}

panic / recover 源码注释

// The panic built-in function stops normal execution of the current
// goroutine. When a function F calls panic, normal execution of F stops
// immediately. Any functions whose execution was deferred by F are run in
// the usual way, and then F returns to its caller. To the caller G, the
// invocation of F then behaves like a call to panic, terminating G's
// execution and running any deferred functions. This continues until all
// functions in the executing goroutine have stopped, in reverse order. At
// that point, the program is terminated with a non-zero exit code. This
// termination sequence is called panicking and can be controlled by the
// built-in function recover.
func panic(v any)

// The recover built-in function allows a program to manage behavior of a
// panicking goroutine. Executing a call to recover inside a deferred
// function (but not any function called by it) stops the panicking sequence
// by restoring normal execution and retrieves the error value passed to the
// call of panic. If recover is called outside the deferred function it will
// not stop a panicking sequence. In this case, or when the goroutine is not
// panicking, or if the argument supplied to panic was nil, recover returns
// nil. Thus the return value from recover reports whether the goroutine is
// panicking.
func recover() any

runtime.Stack(buf []byte, all bool) int


// Stack formats a stack trace of the calling goroutine into buf
// and returns the number of bytes written to buf.
// If all is true, Stack formats stack traces of all other goroutines
// into buf after the trace for the current goroutine.
func Stack(buf []byte, all bool) int {
    if all {
        stopTheWorld("stack trace")
    }

    n := 0
    if len(buf) > 0 {
        gp := getg()
        sp := getcallersp()
        pc := getcallerpc()
        systemstack(func() {
            g0 := getg()
            // Force traceback=1 to override GOTRACEBACK setting,
            // so that Stack's results are consistent.
            // GOTRACEBACK is only about crash dumps.
            g0.m.traceback = 1
            g0.writebuf = buf[0:0:len(buf)]
            goroutineheader(gp)
            traceback(pc, sp, 0, gp)
            if all {
                tracebackothers(gp)
            }
            g0.m.traceback = 0
            n = len(g0.writebuf)
            g0.writebuf = nil
        })
    }

    if all {
        startTheWorld()
    }
    return n
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 2024年1月16日再看 1.18 源代码的时候发现代码已经发生了变化。本文档的代码大概在 1.14 左右。 原书...
    Robin92阅读 1,874评论 7 7
  • 目录 统一规范篇 命名篇 开发篇 优化篇 统一规范篇 本篇主要描述了公司内部同事都必须遵守的一些开发规矩,如统一开...
    零一间阅读 1,982评论 0 2
  • fmt格式化字符串 格式:%[旗标][宽度][.精度][arg索引]动词旗标有以下几种:+: 对于数值类型总是输出...
    皮皮v阅读 1,132评论 0 3
  • 原文:https://makeoptim.com/golang/effective-go[https://make...
    CatchZeng阅读 1,861评论 0 1
  • golang中defer,panic,recover是很常用的三个特性,三者一起使用可以充当其他语言中try…ca...
    smoke_zl阅读 27,771评论 2 28