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
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.