douquqiang1513 2018-10-03 07:15
浏览 59
已采纳

将外部错误映射到Golang中的域错误

I have a service type called ComputeService which implements certain domain logic. The service itself depends on implementation of an interface called Computer which has a method Computer.Compute(args...) (value, error). As shown, Compute itself might return certain errors.

ComputeService needs to send appropriate errors from a set of domain-errors with proper domain-error code so that translations can be done and also clients can handle errors appropriately.

My question is, should the Computer implementations be wrapping their failure in domain-errors or should ComputeService do this. If ComputeService is the one doing it, then it will have to know about different errors returned by different implementations of Computer interface which in my opinion breaks the abstraction. Both ways are demonstrated below:

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()
}

OR

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()
    }

}
  • 写回答

2条回答 默认 最新

  • duanchi3109 2018-10-03 18:59
    关注

    Implementors of Computer should respond with the domain errors, since they're the closest ones to the action and best able to determine what an error is. Like you said, having that logic in ComputeService breaks the abstraction. If you need mapping code from specific Computer errors to domain errors, create wrapper structs that separate the main logic from that error wrapping code.

    To keep internal error context, just embed the original error in the domain error and make IsSpecificDomainError helpers.

    type MyDomainError struct {
        Err error
    }
    
    func NewMyDomainErr(err error) error {
        return &MyDomainError{err}
    }
    
    func IsMyDomainError(e error) bool {
        _, ok := err.(*MyDomainError)
        return ok
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 蓝牙耳机怎么查看日志
  • ¥15 R语言 拟时序分析降维图如何减少分支
  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统