【发布时间】:2019-06-21 15:52:31
【问题描述】:
我有一个名为ComputeService 的服务类型,它实现了某些域逻辑。服务本身依赖于名为Computer 的接口的实现,该接口有一个方法Computer.Compute(args...) (value, error)。如图所示,Compute 本身可能会返回某些错误。
ComputeService 需要使用正确的域错误代码从一组域错误中发送适当的错误,以便可以完成翻译并且客户端也可以适当地处理错误。
我的问题是,Computer 实现应该将它们的失败包含在域错误中,还是应该 ComputeService 这样做。如果ComputeService 是这样做的,那么它必须知道Computer 接口的不同实现返回的不同错误,我认为这会破坏抽象。两种方式都演示如下:
package arithmetic
type Computer struct {
}
func (ac Computer) Compute(args ....) (value, error) {
// errors is a domain-errors package defined in compute service project
return errors.NewDivideByZero()
}
或
package compute
type Service struct {
}
func (svc Service) Process(args...) error {
computer := findComputerImplementation(args...)
val, err := computer.Compute(args...)
if err != nil {
if err == arith.ErrDivideByZero {
// converting an arithmetic computer implementation
// specific error to domain error
return errors.NewDivideByZero()
} else if err == algebra.ErrInvalidCoEfficient {
// converting an algebraic computer implementation
// specific error to domain error
return errors.NewBadInput()
}
// some new implementation was used and we have no idea
// what errors it could be returning. so we have to send
// a internal server error equivalent here
return errors.NewInternalError()
}
}
【问题讨论】:
-
或者你可以结合:返回一个包含特定
Computer特定错误的错误类型。 -
喜欢
errors.NewComputerFailure(err)? -
是的......
-
不幸的是,这是不可能的,因为至少,我的 http 处理程序需要区分客户端错误和内部错误。例如,如果
Computer实现依赖于 db/external 服务并且失败了,这是一个内部错误。但是如果客户端发送一个需要除以零的计算请求,这是一个客户端错误。所以将所有Compute错误映射到一个ComputeFailure是行不通的。 -
我不是要求它是自动的。我的问题是应该在哪里生成域错误。
Compute实现应该返回arith、algebra等包中定义的常量错误,ComputeService将其映射到自己的错误类型还是Compute实现本身返回适当的域错误?
标签: go error-handling abstraction