go-zero
go-zero copied to clipboard
how to pass errors in rpc services back into api services?
在写rpc 的时候, 我想把 rpc的某个业务流程方面的错误返回给api. return xx.Reply, errorx.CodeError() 这个errorx.CodeError()对象到api 的时候,类型就不在是 CodeError类型的error了. 现在只能在 reply里面定义code 和msg 我想问下, 好的go-zero项目 关于 rpc返回业务流程错误是怎么做的? 求求大佬给一个好的建议. (业务流程的错误可能有几种)
Try using type assertions
Try using type assertions
好像是没有办法断言的 在到达api层的时候,他的类型已经不是errorx.CodeErr了
Refer to Google's error handling method: https://cloud.google.com/apis/design/errors#error_model
Use status.Status.WithDetails(details ...proto.Message)
to return detailed business errors to the client.
You should not use errorx.CodeError
in your svc or biz layer. errorx.CodeError
is design for api.
I think that each layer of the program should handle and wrap errors individually, and should not throw errors >2 layers, otherwise the error will become un-enumerable when the upper layer handles errors.
Bad
// db layer
var ErrNotFound = errors.New("not found")
func Find() error {
return ErrNotFound
}
// svc layer
func Find() error {
return db.Find()
}
// logic layer
func FindLogic() (int, interface{}) {
err := svc.Find()
if err != nil {
if errors.Is(db.ErrNotFound, err) { // logic layer should not handle error from db layer
return 404, "fail"
} else {
return 200, "success"
}
}
}
Bad
// db layer
var ErrNotFound = errors.New("not found")
func Find() (int, error) {
return 404, ErrNotFound // logic layer should not consider about api error
}
// svc layer
func Find() (int, error) {
return db.Find()
}
// logic layer
func FindLogic() (int, interface{}) {
return svc.Find() // api should not expose db error to user
}
Good
// db layer
var ErrNotFound = errors.New("not found")
func Find() error {
return ErrNotFound
}
// svc layer
var ErrNotFound = errors.New("not found") // wrap the error
func Find() error {
err := db.Find()
if err != nil {
if errors.Is(db.ErrNotFound, err) {
return ErrNotFound
} else {
return nil
}
}
}
// logic layer
func FindLogic() (int, interface{}) {
err := svc.Find()
if err != nil {
if errors.Is(svc.ErrNotFound, err) { // should only handle svc error
return 404, "fail"
} else {
return 200, "success"
}
}
}
Try using type assertions
好像是没有办法断言的 在到达api层的时候,他的类型已经不是errorx.CodeErr了
errorx.CodeErr
is the implement of error
. It should be possible to be asserted
参考肝王的looklook吧,这种方式前端看不到错误信息https://github.com/Mikaelemmmm/go-zero-looklook
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
Please refer to Live King's looklook, this way you can't see the error message on the front end https://github.com/Mikaelemmmm/go-zero-looklook