
本文介绍如何在 go 应用中对 mongodb(以 mgo 为例)返回的错误进行类型断言与分类处理,从而根据具体错误类型(如记录未找到、查询语法错误、写入冲突等)动态返回对应的 http 状态码(如 404、400、500),提升 api 的语义准确性和可调试性。
本文介绍如何在 go 应用中对 mongodb(以 mgo 为例)返回的错误进行类型断言与分类处理,从而根据具体错误类型(如记录未找到、查询语法错误、写入冲突等)动态返回对应的 http 状态码(如 404、400、500),提升 api 的语义准确性和可调试性。
在 Go 中使用 mgo 驱动操作 MongoDB 时,数据库操作失败仅返回通用的 error 接口,无法直接获取结构化错误码。但 mgo 实际提供了若干导出的错误类型(如 mgo.ErrNotFound、*mgo.QueryError、*mgo.LastError),它们实现了 error 接口,可通过 类型断言(type switch) 提取并区分语义。
以下是推荐的错误分类处理模式:
import (
"gopkg.in/mgo.v2"
"net/http"
)
func (s *State) Index(c *gin.Context) {
res, err := s.DB.GetArticles()
if err != nil {
var statusCode int
var title, detail string
switch e := err.(type) {
case *mgo.QueryError:
statusCode = http.StatusBadRequest
title = "Invalid query"
detail = e.Message // 如 "invalid operator: $inval"
case *mgo.LastError:
if e.Code == 11000 || e.Code == 11001 { // 重复键错误
statusCode = http.StatusConflict
title = "Duplicate record"
} else {
statusCode = http.StatusInternalServerError
title = "Database write error"
}
detail = e.Err
case *mgo.ChangeInfo:
// 仅用于 Update/Upsert 返回的 info,非 error,此处不触发
default:
if err == mgo.ErrNotFound {
statusCode = http.StatusNotFound
title = "Record not found"
detail = "No document matched the query"
} else {
statusCode = http.StatusInternalServerError
title = "Internal database error"
detail = err.Error()
}
}
c.JSON(statusCode, gin.H{
"error": gin.H{
"status": strconv.Itoa(statusCode),
"title": title,
"detail": detail,
},
})
return
}
// 成功响应
content := gin.H{
"data": gin.H{
"type": "records",
"id": res.Id,
"attributes": gin.H{
"Phone": res.Phone,
},
},
}
c.JSON(http.StatusOK, content)
}
⚠️ 注意事项:
- mgo.ErrNotFound 是一个变量(值),不是类型,因此需用 err == mgo.ErrNotFound 判断,而非 case mgo.ErrNotFound:;
- *mgo.QueryError 和 *mgo.LastError 是指针类型,务必带 *;
- mgo.LastError.Code 是 MongoDB 原生错误码(如 11000 表示重复键),可参考 MongoDB 官方错误码列表;
- mgo 已归档(不再维护),生产环境建议迁移到官方驱动 go.mongodb.org/mongo-driver/mongo,其错误体系更完善(如 mongo.IsDuplicateKeyError()、mongo.IsNoDocumentsError() 等辅助函数);
- 若使用官方驱动,应优先使用 errors.Is() 或专用判断函数,而非手动比对错误字符串或字段。
总结:通过类型断言精准识别 mgo 错误子类型,结合 MongoDB 错误码语义,即可构建健壮、符合 REST 规范的错误响应体系——这不仅提升客户端体验,也大幅简化服务端日志分析与问题定位。











