面试题答案
一键面试错误处理和错误链构建思路
- 每层错误捕获:在每个函数调用处捕获可能出现的错误,确保不会遗漏任何异常情况。
- 错误链构建:将业务层面的错误与底层可能出现的错误进行关联,以便于排查问题。
- 错误传播:将构建好的错误链向上层函数传播,直到最顶层的调用者处理。
关键代码示例(以Go语言为例)
package main
import (
"fmt"
)
// 假设的结构体
type OrderInfo struct {
ProductID string
UserID string
}
// 库存检查函数
func checkStock(productID string) error {
// 模拟库存不足错误
if productID == "123" {
return fmt.Errorf("库存不足错误: 产品 %s 库存不足", productID)
}
return nil
}
// 用户余额检查函数
func checkBalance(userID string) error {
// 模拟余额不足错误
if userID == "456" {
return fmt.Errorf("余额不足错误: 用户 %s 余额不足", userID)
}
return nil
}
// 订单创建函数
func createOrder(orderInfo OrderInfo) error {
// 模拟数据库连接错误
if orderInfo.ProductID == "789" {
return fmt.Errorf("底层数据库连接错误: 连接数据库失败")
}
return nil
}
// 下单主函数
func placeOrder(orderInfo OrderInfo) error {
var err error
if err = checkStock(orderInfo.ProductID); err != nil {
return fmt.Errorf("业务层面错误: 库存检查失败: %w", err)
}
if err = checkBalance(orderInfo.UserID); err != nil {
return fmt.Errorf("业务层面错误: 用户余额检查失败: %w", err)
}
if err = createOrder(orderInfo); err != nil {
return fmt.Errorf("业务层面错误: 订单创建失败: %w", err)
}
return nil
}
你可以使用以下方式调用:
func main() {
order := OrderInfo{
ProductID: "123",
UserID: "456",
}
if err := placeOrder(order); err != nil {
fmt.Println(err)
}
}