diff --git a/pkg/errs/errno.go b/pkg/errs/errno.go index cd4fab2f9a2..8182f47fd4c 100644 --- a/pkg/errs/errno.go +++ b/pkg/errs/errno.go @@ -62,3 +62,24 @@ var ( ErrEtcdKVSave = errors.Normalize("etcd KV save failed", errors.RFCCodeText("PD:kv:ErrEtcdKVSave")) ErrEtcdKVRemove = errors.Normalize("etcd KV remove failed", errors.RFCCodeText("PD:kv:ErrEtcdKVRemove")) ) + +// scheduler errors +var ( + ErrGetSourceStore = errors.Normalize("failed to get the source store", errors.RFCCodeText("PD:scheduler:ErrGetSourceStore")) + ErrSchedulerExisted = errors.Normalize("scheduler existed", errors.RFCCodeText("PD:scheduler:ErrSchedulerExisted")) + ErrSchedulerNotFound = errors.Normalize("scheduler not found", errors.RFCCodeText("PD:scheduler:ErrSchedulerNotFound")) + ErrScheduleConfigNotExist = errors.Normalize("the config does not exist", errors.RFCCodeText("PD:scheduler:ErrScheduleConfigNotExist")) + ErrSchedulerConfig = errors.Normalize("wrong scheduler config %s", errors.RFCCodeText("PD:scheduler:ErrSchedulerConfig")) + ErrCacheOverflow = errors.Normalize("cache overflow", errors.RFCCodeText("PD:scheduler:ErrCacheOverflow")) + ErrInternalGrowth = errors.Normalize("unknown interval growth type error", errors.RFCCodeText("PD:scheduler:ErrInternalGrowth")) +) + +// strconv errors +var ( + ErrStrconvParseUint = errors.Normalize("parse uint error", errors.RFCCodeText("PD:strconv:ErrStrconvParseUint")) +) + +// url errors +var ( + ErrQueryUnescape = errors.Normalize("inverse transformation of QueryEscape error", errors.RFCCodeText("PD:url:ErrQueryUnescape")) +) diff --git a/pkg/errs/errs.go b/pkg/errs/errs.go index a4c2eb7afb9..1509b26af4d 100644 --- a/pkg/errs/errs.go +++ b/pkg/errs/errs.go @@ -20,7 +20,13 @@ import ( ) // ZapError is used to make the log output eaiser. -func ZapError(err *errors.Error, causeError error) zap.Field { - e := err.Wrap(causeError).FastGenWithCause() - return zap.Field{Key: "error", Type: zapcore.ErrorType, Interface: e} +func ZapError(err error, causeError ...error) zap.Field { + if e, ok := err.(*errors.Error); ok { + if len(causeError) >= 1 { + err = e.Wrap(causeError[0]).FastGenWithCause() + } else { + err = e.FastGenByArgs() + } + } + return zap.Field{Key: "error", Type: zapcore.ErrorType, Interface: err} } diff --git a/pkg/errs/errs_test.go b/pkg/errs/errs_test.go index 6f6f0b013c1..ec04ba55492 100644 --- a/pkg/errs/errs_test.go +++ b/pkg/errs/errs_test.go @@ -92,3 +92,38 @@ func (s *testErrorSuite) TestError(c *C) { fmt.Println(lg.Message()) c.Assert(strings.Contains(lg.Message(), rfc), IsTrue) } + +func (s *testErrorSuite) TestErrorEqual(c *C) { + err1 := ErrSchedulerNotFound.FastGenByArgs() + err2 := ErrSchedulerNotFound.FastGenByArgs() + c.Assert(errors.ErrorEqual(err1, err2), IsTrue) + + err := errors.New("test") + err1 = ErrSchedulerNotFound.Wrap(err).FastGenWithCause() + err2 = ErrSchedulerNotFound.Wrap(err).FastGenWithCause() + c.Assert(errors.ErrorEqual(err1, err2), IsTrue) + + err1 = ErrSchedulerNotFound.FastGenByArgs() + err2 = ErrSchedulerNotFound.Wrap(err).FastGenWithCause() + c.Assert(errors.ErrorEqual(err1, err2), IsFalse) + + err3 := errors.New("test") + err4 := errors.New("test") + err1 = ErrSchedulerNotFound.Wrap(err3).FastGenWithCause() + err2 = ErrSchedulerNotFound.Wrap(err4).FastGenWithCause() + c.Assert(errors.ErrorEqual(err1, err2), IsTrue) + + err3 = errors.New("test1") + err4 = errors.New("test") + err1 = ErrSchedulerNotFound.Wrap(err3).FastGenWithCause() + err2 = ErrSchedulerNotFound.Wrap(err4).FastGenWithCause() + c.Assert(errors.ErrorEqual(err1, err2), IsFalse) +} + +func (s *testErrorSuite) TestZapError(c *C) { + err := errors.New("test") + log.Info("test", ZapError(err)) + err1 := ErrSchedulerNotFound + log.Info("test", ZapError(err1)) + log.Info("test", ZapError(err1, err)) +} diff --git a/server/api/scheduler.go b/server/api/scheduler.go index 9067fbb9fe2..cb3cae54e26 100644 --- a/server/api/scheduler.go +++ b/server/api/scheduler.go @@ -20,7 +20,9 @@ import ( "strings" "github.com/gorilla/mux" + "github.com/pingcap/errors" "github.com/tikv/pd/pkg/apiutil" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server" "github.com/tikv/pd/server/schedulers" "github.com/unrolled/render" @@ -147,13 +149,13 @@ func (h *schedulerHandler) Post(w http.ResponseWriter, r *http.Request) { return } err := h.AddGrantLeaderScheduler(uint64(storeID)) - if err == schedulers.ErrSchedulerExisted { + if errors.ErrorEqual(err, errs.ErrSchedulerExisted.FastGenByArgs()) { if err := h.redirectSchedulerUpdate(schedulers.GrantLeaderName, storeID); err != nil { h.r.JSON(w, http.StatusInternalServerError, err.Error()) return } } - if err != nil && err != schedulers.ErrSchedulerExisted { + if err != nil && !errors.ErrorEqual(err, errs.ErrSchedulerExisted.FastGenByArgs()) { h.r.JSON(w, http.StatusInternalServerError, err.Error()) return } @@ -164,13 +166,13 @@ func (h *schedulerHandler) Post(w http.ResponseWriter, r *http.Request) { return } err := h.AddEvictLeaderScheduler(uint64(storeID)) - if err == schedulers.ErrSchedulerExisted { + if errors.ErrorEqual(err, errs.ErrSchedulerExisted.FastGenByArgs()) { if err := h.redirectSchedulerUpdate(schedulers.EvictLeaderName, storeID); err != nil { h.r.JSON(w, http.StatusInternalServerError, err.Error()) return } } - if err != nil && err != schedulers.ErrSchedulerExisted { + if err != nil && !errors.ErrorEqual(err, errs.ErrSchedulerExisted.FastGenByArgs()) { h.r.JSON(w, http.StatusInternalServerError, err.Error()) return } @@ -250,7 +252,7 @@ func (h *schedulerHandler) Delete(w http.ResponseWriter, r *http.Request) { } func (h *schedulerHandler) handleErr(w http.ResponseWriter, err error) { - if err == schedulers.ErrSchedulerNotFound { + if errors.ErrorEqual(err, errs.ErrSchedulerNotFound.FastGenByArgs()) { h.r.JSON(w, http.StatusNotFound, err.Error()) } else { h.r.JSON(w, http.StatusInternalServerError, err.Error()) @@ -263,7 +265,7 @@ func (h *schedulerHandler) redirectSchedulerDelete(name, schedulerName string) e url := fmt.Sprintf("%s/%s/%s/delete/%s", h.GetAddr(), schedulerConfigPrefix, schedulerName, args[0]) resp, err := doDelete(h.svr.GetHTTPClient(), url) if resp.StatusCode != 200 { - return schedulers.ErrSchedulerNotFound + return errs.ErrSchedulerNotFound.FastGenByArgs() } if err != nil { return err diff --git a/server/cluster/cluster_worker.go b/server/cluster/cluster_worker.go index 9005b3d3c56..b106004ac1b 100644 --- a/server/cluster/cluster_worker.go +++ b/server/cluster/cluster_worker.go @@ -21,9 +21,9 @@ import ( "github.com/pingcap/kvproto/pkg/pdpb" "github.com/pingcap/log" "github.com/pkg/errors" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" - "github.com/tikv/pd/server/schedulers" "go.uber.org/zap" ) @@ -112,7 +112,7 @@ func (c *RaftCluster) HandleAskBatchSplit(request *pdpb.AskBatchSplitRequest) (* for i := 0; i < int(splitCount); i++ { newRegionID, err := c.id.Alloc() if err != nil { - return nil, schedulers.ErrSchedulerNotFound + return nil, errs.ErrSchedulerNotFound.FastGenByArgs() } peerIDs := make([]uint64, len(request.Region.Peers)) diff --git a/server/cluster/coordinator.go b/server/cluster/coordinator.go index f2124a2dce3..9f33225d728 100644 --- a/server/cluster/coordinator.go +++ b/server/cluster/coordinator.go @@ -22,8 +22,9 @@ import ( "sync/atomic" "time" + "github.com/pingcap/errors" "github.com/pingcap/log" - "github.com/pkg/errors" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/pkg/keyutil" "github.com/tikv/pd/pkg/logutil" "github.com/tikv/pd/server/config" @@ -293,7 +294,7 @@ func (c *coordinator) run() { } log.Info("create scheduler", zap.String("scheduler-name", s.GetName())) - if err = c.addScheduler(s, schedulerCfg.Args...); err != nil && err != schedulers.ErrSchedulerExisted { + if err = c.addScheduler(s, schedulerCfg.Args...); err != nil && !errors.ErrorEqual(err, errs.ErrSchedulerExisted.FastGenByArgs()) { log.Error("can not add scheduler", zap.String("scheduler-name", s.GetName()), zap.Error(err)) } else { // Only records the valid scheduler config. @@ -533,7 +534,7 @@ func (c *coordinator) addScheduler(scheduler schedule.Scheduler, args ...string) defer c.Unlock() if _, ok := c.schedulers[scheduler.GetName()]; ok { - return schedulers.ErrSchedulerExisted + return errs.ErrSchedulerExisted.FastGenByArgs() } s := newScheduleController(c, scheduler) @@ -556,7 +557,7 @@ func (c *coordinator) removeScheduler(name string) error { } s, ok := c.schedulers[name] if !ok { - return schedulers.ErrSchedulerNotFound + return errs.ErrSchedulerNotFound.FastGenByArgs() } s.Stop() @@ -588,7 +589,7 @@ func (c *coordinator) pauseOrResumeScheduler(name string, t int64) error { if name != "all" { sc, ok := c.schedulers[name] if !ok { - return schedulers.ErrSchedulerNotFound + return errs.ErrSchedulerNotFound.FastGenByArgs() } s = append(s, sc) } else { @@ -615,7 +616,7 @@ func (c *coordinator) isSchedulerPaused(name string) (bool, error) { } s, ok := c.schedulers[name] if !ok { - return false, schedulers.ErrSchedulerNotFound + return false, errs.ErrSchedulerNotFound.FastGenByArgs() } return s.IsPaused(), nil } diff --git a/server/schedulers/adjacent_region.go b/server/schedulers/adjacent_region.go index d48365104ff..aeb2c3e16f8 100644 --- a/server/schedulers/adjacent_region.go +++ b/server/schedulers/adjacent_region.go @@ -20,7 +20,7 @@ import ( "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" - "github.com/pkg/errors" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/filter" @@ -47,16 +47,16 @@ func init() { return func(v interface{}) error { conf, ok := v.(*balanceAdjacentRegionConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } if len(args) == 2 { leaderLimit, err := strconv.ParseUint(args[0], 10, 64) if err != nil { - return errors.WithStack(err) + return errs.ErrStrconvParseUint.Wrap(err).FastGenWithCause() } peerLimit, err := strconv.ParseUint(args[1], 10, 64) if err != nil { - return errors.WithStack(err) + return errs.ErrStrconvParseUint.Wrap(err).FastGenWithCause() } conf.LeaderLimit = leaderLimit conf.PeerLimit = peerLimit @@ -233,7 +233,7 @@ func (l *balanceAdjacentRegionScheduler) process(cluster opt.Cluster) []*operato defer func() { if l.cacheRegions.len() < 0 { - log.Fatal("cache overflow", zap.String("scheduler", l.GetName())) + log.Fatal("cache overflow", zap.String("scheduler", l.GetName()), errs.ZapError(errs.ErrCacheOverflow)) } l.cacheRegions.head = head + 1 l.lastKey = r2.GetStartKey() @@ -262,10 +262,10 @@ func (l *balanceAdjacentRegionScheduler) unsafeToBalance(cluster opt.Cluster, re if !opt.IsRegionReplicated(cluster, region) { return true } - storeID := region.GetLeader().GetStoreId() - store := cluster.GetStore(storeID) + leaderStoreID := region.GetLeader().GetStoreId() + store := cluster.GetStore(leaderStoreID) if store == nil { - log.Error("failed to get the store", zap.Uint64("store-id", storeID)) + log.Error("failed to get the store", zap.Uint64("store-id", leaderStoreID), errs.ZapError(errs.ErrGetSourceStore)) return true } s := l.selector.SelectSource(cluster, []*core.StoreInfo{store}) @@ -300,7 +300,7 @@ func (l *balanceAdjacentRegionScheduler) disperseLeader(cluster opt.Cluster, bef } op, err := operator.CreateTransferLeaderOperator("balance-adjacent-leader", cluster, before, before.GetLeader().GetStoreId(), target.GetID(), operator.OpAdjacent) if err != nil { - log.Debug("fail to create transfer leader operator", zap.Error(err)) + log.Debug("fail to create transfer leader operator", errs.ZapError(err)) return nil } op.SetPriorityLevel(core.LowPriority) @@ -317,7 +317,7 @@ func (l *balanceAdjacentRegionScheduler) dispersePeer(cluster opt.Cluster, regio stores := cluster.GetRegionStores(region) source := cluster.GetStore(leaderStoreID) if source == nil { - log.Error("failed to get the source store", zap.Uint64("store-id", leaderStoreID)) + log.Error("failed to get the source store", zap.Uint64("store-id", leaderStoreID), errs.ZapError(errs.ErrGetSourceStore)) return nil } var scoreGuard filter.Filter diff --git a/server/schedulers/balance_leader.go b/server/schedulers/balance_leader.go index 5934dae5a6e..22953617402 100644 --- a/server/schedulers/balance_leader.go +++ b/server/schedulers/balance_leader.go @@ -18,8 +18,8 @@ import ( "strconv" "github.com/pingcap/log" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/filter" @@ -42,11 +42,11 @@ func init() { return func(v interface{}) error { conf, ok := v.(*balanceLeaderSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } ranges, err := getKeyRanges(args) if err != nil { - return errors.WithStack(err) + return err } conf.Ranges = ranges conf.Name = BalanceLeaderName @@ -78,7 +78,7 @@ type balanceLeaderScheduler struct { // newBalanceLeaderScheduler creates a scheduler that tends to keep leaders on // each store balanced. -func newBalanceLeaderScheduler(opController *schedule.OperatorController, conf *balanceLeaderSchedulerConfig, opts ...BalanceLeaderCreateOption) schedule.Scheduler { +func newBalanceLeaderScheduler(opController *schedule.OperatorController, conf *balanceLeaderSchedulerConfig, options ...BalanceLeaderCreateOption) schedule.Scheduler { base := NewBaseScheduler(opController) s := &balanceLeaderScheduler{ @@ -87,8 +87,8 @@ func newBalanceLeaderScheduler(opController *schedule.OperatorController, conf * opController: opController, counter: balanceLeaderCounter, } - for _, opt := range opts { - opt(s) + for _, option := range options { + option(s) } s.filters = []filter.Filter{ filter.StoreStateFilter{ActionScope: s.GetName(), TransferLeader: true}, @@ -280,7 +280,7 @@ func (l *balanceLeaderScheduler) createOperator(cluster opt.Cluster, region *cor op, err := operator.CreateTransferLeaderOperator(BalanceLeaderType, cluster, region, region.GetLeader().GetStoreId(), targetID, operator.OpBalance) if err != nil { - log.Debug("fail to create balance leader operator", zap.Error(err)) + log.Debug("fail to create balance leader operator", errs.ZapError(err)) return nil } sourceLabel := strconv.FormatUint(sourceID, 10) diff --git a/server/schedulers/balance_region.go b/server/schedulers/balance_region.go index bcb13caf677..f0d3ac719aa 100644 --- a/server/schedulers/balance_region.go +++ b/server/schedulers/balance_region.go @@ -19,8 +19,8 @@ import ( "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" - "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/checker" @@ -35,11 +35,11 @@ func init() { return func(v interface{}) error { conf, ok := v.(*balanceRegionSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } ranges, err := getKeyRanges(args) if err != nil { - return errors.WithStack(err) + return err } conf.Ranges = ranges conf.Name = BalanceRegionName @@ -191,7 +191,7 @@ func (s *balanceRegionScheduler) transferPeer(cluster opt.Cluster, region *core. sourceStoreID := oldPeer.GetStoreId() source := cluster.GetStore(sourceStoreID) if source == nil { - log.Error("failed to get the source store", zap.Uint64("store-id", sourceStoreID)) + log.Error("failed to get the source store", zap.Uint64("store-id", sourceStoreID), errs.ZapError(errs.ErrGetSourceStore)) return nil } exclude := make(map[uint64]struct{}) diff --git a/server/schedulers/base_scheduler.go b/server/schedulers/base_scheduler.go index a068ed8f42d..67d8b1039cd 100644 --- a/server/schedulers/base_scheduler.go +++ b/server/schedulers/base_scheduler.go @@ -19,6 +19,7 @@ import ( "time" "github.com/pingcap/log" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/opt" ) @@ -50,7 +51,7 @@ func intervalGrow(x time.Duration, maxInterval time.Duration, typ intervalGrowth case zeroGrowth: return x default: - log.Fatal("unknown interval growth type") + log.Fatal("type error", errs.ZapError(errs.ErrInternalGrowth)) } return 0 } diff --git a/server/schedulers/evict_leader.go b/server/schedulers/evict_leader.go index 88d5cb0c516..d3ac87977a3 100644 --- a/server/schedulers/evict_leader.go +++ b/server/schedulers/evict_leader.go @@ -19,9 +19,10 @@ import ( "sync" "github.com/gorilla/mux" + "github.com/pingcap/errors" "github.com/pingcap/log" - "github.com/pkg/errors" "github.com/tikv/pd/pkg/apiutil" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/filter" @@ -29,7 +30,6 @@ import ( "github.com/tikv/pd/server/schedule/opt" "github.com/tikv/pd/server/schedule/selector" "github.com/unrolled/render" - "go.uber.org/zap" ) const ( @@ -47,20 +47,20 @@ func init() { schedule.RegisterSliceDecoderBuilder(EvictLeaderType, func(args []string) schedule.ConfigDecoder { return func(v interface{}) error { if len(args) != 1 { - return errors.New("should specify the store-id") + return errs.ErrSchedulerConfig.FastGenByArgs("id") } conf, ok := v.(*evictLeaderSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } id, err := strconv.ParseUint(args[0], 10, 64) if err != nil { - return errors.WithStack(err) + return errs.ErrStrconvParseUint.Wrap(err).FastGenWithCause() } ranges, err := getKeyRanges(args[1:]) if err != nil { - return errors.WithStack(err) + return err } conf.StoreIDWithRanges[id] = ranges return nil @@ -87,16 +87,16 @@ type evictLeaderSchedulerConfig struct { func (conf *evictLeaderSchedulerConfig) BuildWithArgs(args []string) error { if len(args) != 1 { - return errors.New("should specify the store-id") + return errs.ErrSchedulerConfig.FastGenByArgs("id") } id, err := strconv.ParseUint(args[0], 10, 64) if err != nil { - return errors.WithStack(err) + return errs.ErrStrconvParseUint.Wrap(err).FastGenWithCause() } ranges, err := getKeyRanges(args[1:]) if err != nil { - return errors.WithStack(err) + return err } conf.mu.Lock() defer conf.mu.Unlock() @@ -234,7 +234,7 @@ func (s *evictLeaderScheduler) scheduleOnce(cluster opt.Cluster) []*operator.Ope } op, err := operator.CreateTransferLeaderOperator(EvictLeaderType, cluster, region, region.GetLeader().GetStoreId(), target.GetID(), operator.OpLeader) if err != nil { - log.Debug("fail to create evict leader operator", zap.Error(err)) + log.Debug("fail to create evict leader operator", errs.ZapError(err)) continue } op.SetPriorityLevel(core.HighPriority) @@ -345,8 +345,8 @@ func (handler *evictLeaderHandler) DeleteConfig(w http.ResponseWriter, r *http.R } if last { if err := handler.config.cluster.RemoveScheduler(EvictLeaderName); err != nil { - if err == ErrSchedulerNotFound { - handler.rd.JSON(w, http.StatusNotFound, err.Error()) + if errors.ErrorEqual(err, errs.ErrSchedulerNotFound.FastGenByArgs()) { + handler.rd.JSON(w, http.StatusNotFound, err) } else { handler.rd.JSON(w, http.StatusInternalServerError, err.Error()) } @@ -358,7 +358,7 @@ func (handler *evictLeaderHandler) DeleteConfig(w http.ResponseWriter, r *http.R return } - handler.rd.JSON(w, http.StatusNotFound, ErrScheduleConfigNotExist.Error()) + handler.rd.JSON(w, http.StatusNotFound, errs.ErrScheduleConfigNotExist.FastGenByArgs()) } func newEvictLeaderHandler(config *evictLeaderSchedulerConfig) http.Handler { diff --git a/server/schedulers/grant_leader.go b/server/schedulers/grant_leader.go index e8067163ecc..1fd93b01507 100644 --- a/server/schedulers/grant_leader.go +++ b/server/schedulers/grant_leader.go @@ -19,15 +19,15 @@ import ( "sync" "github.com/gorilla/mux" + "github.com/pingcap/errors" "github.com/pingcap/log" - "github.com/pkg/errors" "github.com/tikv/pd/pkg/apiutil" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/operator" "github.com/tikv/pd/server/schedule/opt" "github.com/unrolled/render" - "go.uber.org/zap" ) const ( @@ -41,21 +41,21 @@ func init() { schedule.RegisterSliceDecoderBuilder(GrantLeaderType, func(args []string) schedule.ConfigDecoder { return func(v interface{}) error { if len(args) != 1 { - return errors.New("should specify the store-id") + return errs.ErrSchedulerConfig.FastGenByArgs("id") } conf, ok := v.(*grantLeaderSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } id, err := strconv.ParseUint(args[0], 10, 64) if err != nil { - return errors.WithStack(err) + return errs.ErrStrconvParseUint.Wrap(err).FastGenWithCause() } ranges, err := getKeyRanges(args[1:]) if err != nil { - return errors.WithStack(err) + return err } conf.StoreIDWithRanges[id] = ranges return nil @@ -81,16 +81,16 @@ type grantLeaderSchedulerConfig struct { func (conf *grantLeaderSchedulerConfig) BuildWithArgs(args []string) error { if len(args) != 1 { - return errors.New("should specify the store-id") + return errs.ErrSchedulerConfig.FastGenByArgs("id") } id, err := strconv.ParseUint(args[0], 10, 64) if err != nil { - return errors.WithStack(err) + return errs.ErrStrconvParseUint.Wrap(err).FastGenWithCause() } ranges, err := getKeyRanges(args[1:]) if err != nil { - return errors.WithStack(err) + return err } conf.mu.Lock() defer conf.mu.Unlock() @@ -220,7 +220,7 @@ func (s *grantLeaderScheduler) Schedule(cluster opt.Cluster) []*operator.Operato op, err := operator.CreateTransferLeaderOperator(GrantLeaderType, cluster, region, region.GetLeader().GetStoreId(), id, operator.OpLeader) if err != nil { - log.Debug("fail to create grant leader operator", zap.Error(err)) + log.Debug("fail to create grant leader operator", errs.ZapError(err)) continue } op.Counters = append(op.Counters, schedulerCounter.WithLabelValues(s.GetName(), "new-operator")) @@ -295,8 +295,8 @@ func (handler *grantLeaderHandler) DeleteConfig(w http.ResponseWriter, r *http.R } if last { if err := handler.config.cluster.RemoveScheduler(GrantLeaderName); err != nil { - if err == ErrSchedulerNotFound { - handler.rd.JSON(w, http.StatusNotFound, err.Error()) + if errors.ErrorEqual(err, errs.ErrSchedulerNotFound.FastGenByArgs()) { + handler.rd.JSON(w, http.StatusNotFound, err) } else { handler.rd.JSON(w, http.StatusInternalServerError, err.Error()) } @@ -308,7 +308,7 @@ func (handler *grantLeaderHandler) DeleteConfig(w http.ResponseWriter, r *http.R return } - handler.rd.JSON(w, http.StatusNotFound, ErrScheduleConfigNotExist.Error()) + handler.rd.JSON(w, http.StatusNotFound, errs.ErrScheduleConfigNotExist.FastGenByArgs()) } func newGrantLeaderHandler(config *grantLeaderSchedulerConfig) http.Handler { diff --git a/server/schedulers/hot_region.go b/server/schedulers/hot_region.go index 9eed738bbdb..3dfd4fbb889 100644 --- a/server/schedulers/hot_region.go +++ b/server/schedulers/hot_region.go @@ -26,6 +26,7 @@ import ( "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" "github.com/prometheus/client_golang/prometheus" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/filter" @@ -627,7 +628,7 @@ func (bs *balanceSolver) filterSrcStores() map[uint64]*storeLoadDetail { ret := make(map[uint64]*storeLoadDetail) for id, detail := range bs.stLoadDetail { if bs.cluster.GetStore(id) == nil { - log.Error("failed to get the source store", zap.Uint64("store-id", id)) + log.Error("failed to get the source store", zap.Uint64("store-id", id), errs.ZapError(errs.ErrGetSourceStore)) continue } if len(detail.HotPeers) == 0 { @@ -1053,7 +1054,7 @@ func (bs *balanceSolver) buildOperators() ([]*operator.Operator, []Influence) { } if err != nil { - log.Debug("fail to create operator", zap.Error(err), zap.Stringer("rwType", bs.rwTy), zap.Stringer("opType", bs.opTy)) + log.Debug("fail to create operator", zap.Stringer("rwType", bs.rwTy), zap.Stringer("opType", bs.opTy), errs.ZapError(err)) schedulerCounter.WithLabelValues(bs.sche.GetName(), "create-operator-fail").Inc() return nil, nil } diff --git a/server/schedulers/label.go b/server/schedulers/label.go index b85c762938b..ff7945dbd76 100644 --- a/server/schedulers/label.go +++ b/server/schedulers/label.go @@ -15,7 +15,7 @@ package schedulers import ( "github.com/pingcap/log" - "github.com/pkg/errors" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/filter" @@ -37,11 +37,11 @@ func init() { return func(v interface{}) error { conf, ok := v.(*labelSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } ranges, err := getKeyRanges(args) if err != nil { - return errors.WithStack(err) + return err } conf.Ranges = ranges conf.Name = LabelName @@ -134,7 +134,7 @@ func (s *labelScheduler) Schedule(cluster opt.Cluster) []*operator.Operator { op, err := operator.CreateTransferLeaderOperator("label-reject-leader", cluster, region, id, target.GetID(), operator.OpLeader) if err != nil { - log.Debug("fail to create transfer label reject leader operator", zap.Error(err)) + log.Debug("fail to create transfer label reject leader operator", errs.ZapError(err)) return nil } op.Counters = append(op.Counters, schedulerCounter.WithLabelValues(s.GetName(), "new-operator")) diff --git a/server/schedulers/random_merge.go b/server/schedulers/random_merge.go index 889a450ff0c..447748d7d67 100644 --- a/server/schedulers/random_merge.go +++ b/server/schedulers/random_merge.go @@ -17,7 +17,7 @@ import ( "math/rand" "github.com/pingcap/log" - "github.com/pkg/errors" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/checker" @@ -25,7 +25,6 @@ import ( "github.com/tikv/pd/server/schedule/operator" "github.com/tikv/pd/server/schedule/opt" "github.com/tikv/pd/server/schedule/selector" - "go.uber.org/zap" ) const ( @@ -40,11 +39,11 @@ func init() { return func(v interface{}) error { conf, ok := v.(*randomMergeSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } ranges, err := getKeyRanges(args) if err != nil { - return errors.WithStack(err) + return err } conf.Ranges = ranges conf.Name = RandomMergeName @@ -132,7 +131,7 @@ func (s *randomMergeScheduler) Schedule(cluster opt.Cluster) []*operator.Operato ops, err := operator.CreateMergeRegionOperator(RandomMergeType, cluster, region, target, operator.OpAdmin) if err != nil { - log.Debug("fail to create merge region operator", zap.Error(err)) + log.Debug("fail to create merge region operator", errs.ZapError(err)) return nil } ops[0].Counters = append(ops[0].Counters, schedulerCounter.WithLabelValues(s.GetName(), "new-operator")) diff --git a/server/schedulers/scatter_range.go b/server/schedulers/scatter_range.go index f05a3b57600..2b3ba6e6bc0 100644 --- a/server/schedulers/scatter_range.go +++ b/server/schedulers/scatter_range.go @@ -21,6 +21,7 @@ import ( "github.com/gorilla/mux" "github.com/pkg/errors" "github.com/tikv/pd/pkg/apiutil" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/operator" @@ -33,14 +34,14 @@ func init() { schedule.RegisterSliceDecoderBuilder(ScatterRangeType, func(args []string) schedule.ConfigDecoder { return func(v interface{}) error { if len(args) != 3 { - return errors.New("should specify the range and the name") + return errs.ErrSchedulerConfig.FastGenByArgs("ranges and name") } if len(args[2]) == 0 { - return errors.New("the range name is invalid") + return errs.ErrSchedulerConfig.FastGenByArgs("range name") } conf, ok := v.(*scatterRangeSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } conf.StartKey = args[0] conf.EndKey = args[1] @@ -58,7 +59,7 @@ func init() { } rangeName := conf.RangeName if len(rangeName) == 0 { - return nil, errors.New("the range name is invalid") + return nil, errs.ErrSchedulerConfig.FastGenByArgs("range name") } return newScatterRangeScheduler(opController, conf), nil }) @@ -81,7 +82,7 @@ type scatterRangeSchedulerConfig struct { func (conf *scatterRangeSchedulerConfig) BuildWithArgs(args []string) error { if len(args) != 3 { - return errors.New("scatter range need 3 arguments to setup config") + return errs.ErrSchedulerConfig.FastGenByArgs("ranges and name") } conf.mu.Lock() defer conf.mu.Unlock() diff --git a/server/schedulers/shuffle_hot_region.go b/server/schedulers/shuffle_hot_region.go index 6fbf12589e0..75dfa7d2f5e 100644 --- a/server/schedulers/shuffle_hot_region.go +++ b/server/schedulers/shuffle_hot_region.go @@ -20,6 +20,7 @@ import ( "github.com/pingcap/kvproto/pkg/metapb" "github.com/pingcap/log" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/filter" @@ -40,13 +41,13 @@ func init() { return func(v interface{}) error { conf, ok := v.(*shuffleHotRegionSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } conf.Limit = uint64(1) if len(args) == 1 { limit, err := strconv.ParseUint(args[0], 10, 64) if err != nil { - return err + return errs.ErrStrconvParseUint.Wrap(err).FastGenWithCause() } conf.Limit = limit } @@ -165,7 +166,7 @@ func (s *shuffleHotRegionScheduler) randomSchedule(cluster opt.Cluster, loadDeta srcStoreID := srcRegion.GetLeader().GetStoreId() srcStore := cluster.GetStore(srcStoreID) if srcStore == nil { - log.Error("failed to get the source store", zap.Uint64("store-id", srcStoreID)) + log.Error("failed to get the source store", zap.Uint64("store-id", srcStoreID), errs.ZapError(errs.ErrGetSourceStore)) } var scoreGuard filter.Filter @@ -203,7 +204,7 @@ func (s *shuffleHotRegionScheduler) randomSchedule(cluster opt.Cluster, loadDeta destPeer := &metapb.Peer{StoreId: destStoreID} op, err := operator.CreateMoveLeaderOperator("random-move-hot-leader", cluster, srcRegion, operator.OpRegion|operator.OpLeader, srcStoreID, destPeer) if err != nil { - log.Debug("fail to create move leader operator", zap.Error(err)) + log.Debug("fail to create move leader operator", errs.ZapError(err)) return nil } op.Counters = append(op.Counters, schedulerCounter.WithLabelValues(s.GetName(), "new-operator")) diff --git a/server/schedulers/shuffle_leader.go b/server/schedulers/shuffle_leader.go index 371a1ca3bf5..e3e935fa8b8 100644 --- a/server/schedulers/shuffle_leader.go +++ b/server/schedulers/shuffle_leader.go @@ -15,14 +15,13 @@ package schedulers import ( "github.com/pingcap/log" - "github.com/pkg/errors" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/filter" "github.com/tikv/pd/server/schedule/operator" "github.com/tikv/pd/server/schedule/opt" "github.com/tikv/pd/server/schedule/selector" - "go.uber.org/zap" ) const ( @@ -37,11 +36,11 @@ func init() { return func(v interface{}) error { conf, ok := v.(*shuffleLeaderSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } ranges, err := getKeyRanges(args) if err != nil { - return errors.WithStack(err) + return err } conf.Ranges = ranges conf.Name = ShuffleLeaderName @@ -118,7 +117,7 @@ func (s *shuffleLeaderScheduler) Schedule(cluster opt.Cluster) []*operator.Opera } op, err := operator.CreateTransferLeaderOperator(ShuffleLeaderType, cluster, region, region.GetLeader().GetId(), targetStore.GetID(), operator.OpAdmin) if err != nil { - log.Debug("fail to create shuffle leader operator", zap.Error(err)) + log.Debug("fail to create shuffle leader operator", errs.ZapError(err)) return nil } op.SetPriorityLevel(core.HighPriority) diff --git a/server/schedulers/shuffle_region.go b/server/schedulers/shuffle_region.go index 2f4d04cd792..aad6b4728eb 100644 --- a/server/schedulers/shuffle_region.go +++ b/server/schedulers/shuffle_region.go @@ -17,7 +17,7 @@ import ( "net/http" "github.com/pingcap/kvproto/pkg/metapb" - "github.com/pkg/errors" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule" "github.com/tikv/pd/server/schedule/filter" @@ -38,11 +38,11 @@ func init() { return func(v interface{}) error { conf, ok := v.(*shuffleRegionSchedulerConfig) if !ok { - return ErrScheduleConfigNotExist + return errs.ErrScheduleConfigNotExist.FastGenByArgs() } ranges, err := getKeyRanges(args) if err != nil { - return errors.WithStack(err) + return err } conf.Ranges = ranges conf.Roles = allRoles diff --git a/server/schedulers/utils.go b/server/schedulers/utils.go index 3986c045086..4b3f28319ba 100644 --- a/server/schedulers/utils.go +++ b/server/schedulers/utils.go @@ -21,7 +21,7 @@ import ( "github.com/montanaflynn/stats" "github.com/pingcap/log" - "github.com/pkg/errors" + "github.com/tikv/pd/pkg/errs" "github.com/tikv/pd/server/core" "github.com/tikv/pd/server/schedule/operator" "github.com/tikv/pd/server/schedule/opt" @@ -36,15 +36,6 @@ const ( minTolerantSizeRatio float64 = 1.0 ) -var ( - // ErrSchedulerExisted is error info for scheduler has already existed. - ErrSchedulerExisted = errors.New("scheduler existed") - // ErrSchedulerNotFound is error info for scheduler is not found. - ErrSchedulerNotFound = errors.New("scheduler not found") - // ErrScheduleConfigNotExist the config is not correct. - ErrScheduleConfigNotExist = errors.New("the config does not exist") -) - func minUint64(a, b uint64) uint64 { if a < b { return a @@ -152,11 +143,11 @@ func getKeyRanges(args []string) ([]core.KeyRange, error) { for len(args) > 1 { startKey, err := url.QueryUnescape(args[0]) if err != nil { - return nil, err + return nil, errs.ErrQueryUnescape.Wrap(err).FastGenWithCause() } endKey, err := url.QueryUnescape(args[1]) if err != nil { - return nil, err + return nil, errs.ErrQueryUnescape.Wrap(err).FastGenWithCause() } args = args[2:] ranges = append(ranges, core.NewKeyRange(startKey, endKey))