// // errors.go // Copyright (C) 2024 veypi // 2024-08-01 15:40 // Distributed under terms of the MIT license. // package errs import ( "errors" "fmt" "net/http" "github.com/go-sql-driver/mysql" "github.com/veypi/OneBD/rest" "github.com/veypi/utils/logv" "gorm.io/gorm" ) func JsonResponse(x *rest.X, data any) error { x.WriteHeader(http.StatusOK) return x.JSON(map[string]any{"code": 0, "data": data}) } func JsonErrorResponse(x *rest.X, err error) { code := 50000 var msg string switch e := err.(type) { case *CodeErr: code = e.Code msg = e.Msg case *mysql.MySQLError: if e.Number == 1062 { code = DuplicateKey.Code msg = DuplicateKey.Msg } else { logv.Warn().Msgf("unhandled db error %d: %s", e.Number, err) msg = "db error" } default: if errors.Is(e, gorm.ErrRecordNotFound) { code = NotFound.Code msg = NotFound.Msg } else if errors.Is(e, rest.ErrParse) { code = ArgsInvalid.Code msg = e.Error() } else { logv.Warn().Msgf("unhandled error type: %T\n%s", err, err) msg = e.Error() } } x.WriteHeader(code / 100) x.JSON(map[string]any{"code": code, "err": msg}) } type CodeErr struct { Code int Msg string } func (c *CodeErr) Error() string { return fmt.Sprintf("code: %d, msg: %s", c.Code, c.Msg) } func (c *CodeErr) WithErr(e error) error { c.Msg = fmt.Errorf("%s: %w", c.Msg, e).Error() return c } func (c *CodeErr) WithStr(m string) error { c.Msg = fmt.Errorf("%s: %s", c.Msg, m).Error() return c } // New creates a new CodeMsg. func New(code int, msg string) *CodeErr { return &CodeErr{Code: code, Msg: msg} } var ( ArgsInvalid = New(40001, "args invalid") DuplicateKey = New(40002, "duplicate key") AuthNotFound = New(40100, "auth not found") AuthFailed = New(40101, "auth failed") AuthExpired = New(40102, "auth expired") AuthInvalid = New(40103, "auth invalid") AuthNoPerm = New(40104, "no permission") NotFound = New(40400, "not found") )