MST

星途 面试题库

面试题:Go语言panic与recover在复杂业务逻辑中的应用

假设你正在开发一个涉及多个模块交互的Go程序,某个模块在特定业务条件下可能会出现严重错误需要触发panic。请描述如何设计整个程序结构,使得panic能够在合适的层次被捕获并处理,同时保证其他正常运行的模块不受影响,并且不丢失关键的错误信息,最后给出核心的代码示例。
21.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 分层设计:将程序分为不同的层次,例如业务逻辑层、数据访问层等。这样可以明确各个模块的职责,并且在不同层次捕获和处理错误。
  2. 使用defer和recover:在需要捕获panic的地方使用defer关键字定义一个函数,在这个函数中使用recover函数来捕获panic。
  3. 错误封装:将捕获到的panic信息封装成自定义的错误类型,以便携带更多的上下文信息,同时不丢失关键的错误信息。

核心代码示例

package main

import (
    "fmt"
)

// 自定义错误类型
type BusinessError struct {
    ErrMsg string
}

func (be BusinessError) Error() string {
    return be.ErrMsg
}

// 模拟可能触发panic的函数
func riskyFunction() {
    panic(BusinessError{ErrMsg: "业务条件触发严重错误"})
}

// 捕获panic的函数
func handlePanic() {
    defer func() {
        if r := recover(); r != nil {
            if err, ok := r.(BusinessError); ok {
                fmt.Printf("捕获到业务错误: %v\n", err)
            } else {
                fmt.Printf("捕获到未知错误: %v\n", r)
            }
        }
    }()
    riskyFunction()
}

func main() {
    handlePanic()
    fmt.Println("程序继续正常运行")
}

在上述代码中:

  1. BusinessError是自定义的错误类型,实现了error接口。
  2. riskyFunction模拟了可能触发panic的业务函数。
  3. handlePanic函数使用deferrecover来捕获riskyFunction可能触发的panic,并对其进行处理。如果捕获到的是BusinessError类型的错误,则打印业务错误信息;如果是其他类型的错误,则打印未知错误信息。
  4. main函数调用handlePanic函数,在捕获并处理panic后,程序能够继续正常运行。