# 错误处理

# Gone中定义了三种错误类型:

  • 普通错误
type Error interface {
	error
	Msg() string
	Code() int
}
  • 系统内部错误
type InnerError interface {
	Error
	Stack() []byte
}
  • 业务错误
type BusinessError interface {
	Error
	Data() any
}

# 为什么要定义这三种错误?

做人做事,边界很重要,过犹不及;我们希望通过不同类型的错误定义,厘清团队成员职责的边界。写程序,代码要职责清晰;团队成员职责要清晰明确。简单的讲就是要分清“”是谁的,俗话说“是福不是,是躲不过”。

在Web开发中,我们认为也有三种类型的错误:

# 服务器错误

服务器错误对应HTTP状态码的5XX,代表服务器内部错误,比如:数据库连接失败、文件读取失败、网络请求失败等。这种情况下,“”一般是后端同学或者运维同学的,后端同学要尽快定位并解决问题。

在这种情况下,我们可以使用Gone中定义的InnerError来表示系统错误。可以使用函数gone.NewInnerError来创建,这样创建的InnerError最大的好处是携带了堆栈信息,方便我们定位问题。

Gone Web服务器模块的中间件会拦截系统错误,并返回给客户端一个500状态码。

# 客户端错误

客户端错误对应HTTP状态码的4XX,代表客户端错误,比如:请求参数错误、请求方法错误、请求路径错误等。这种情况,“”一般是前端同学的,前端同学要尽快定位并解决问题。

前端同学应检查参数是否正确,将正确的请求发送给服务器。服务器也必须做错误检查,如果是客户端问题,则需要返回4XX状态码,错误信息应尽量易读,能够指导前端快速找到问题。这里,我们可以使用gone.NewParameterError来创建Gone中定义的Error来表示客户端错误:

err := gone.NewParameterError(
    "参数错误", // 错误信息
    1100, // 错误码,可以省略,默认为400
    400,  // HTTP状态码,可以省略,默认为400
)

# 业务错误

业务错误对应HTTP状态码的200,代表业务错误,比如:用户名或密码错误、用户不存在、用户已存在等。这种情况,“”可能是产品同学的,产品设计问题导致了这种错误。如果错误无法避免,通过产品来引导用户解决;也可能是必要的产品分支设计,比如:用户注册时,需要检查用户名是否已存在。

对于业务错误,可以使用gone.NewBusinessError来创建Gone中定义的BusinessError来表示业务错误,这种错误的最大特点是可以携带业务数据Data:

err := gone.NewBusinessError(
    "订单的信息已经发生变更", // 错误信息
    2100, // 错误码,可以省略,默认为0
    data, // 业务数据
)

这三种错误类型的定义能够帮助我们更好地区分和处理不同类型的错误,使代码和团队职责更加清晰明确。

# 总结

定义三种错误类型的目的是为了更好地区分和处理不同类型的错误,使代码和团队职责更加清晰明确。通过明确划分服务器错误、客户端错误和业务错误,团队成员可以迅速定位并解决问题,确保项目的稳定性和用户体验。系统内部错误(InnerError)帮助后端和运维人员快速定位技术问题;客户端错误(Error)引导前端人员解决请求中的问题;业务错误(BusinessError)则帮助产品和设计人员优化用户流程和体验。这种清晰的职责划分不仅提高了团队的协作效率,也提升了项目的整体质量。