Skip to content

Commit

Permalink
remove registry
Browse files Browse the repository at this point in the history
  • Loading branch information
imtbkcat committed Aug 10, 2020
1 parent a28915e commit 831d046
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 141 deletions.
19 changes: 4 additions & 15 deletions terror_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,10 @@ func (e *Error) RFCCode() RFCErrorCode {
if ec == nil {
return RFCErrorCode(e.ID())
}
reg := ec.registry
// Maybe top-level errors.
if reg.Name == "" {
return RFCErrorCode(fmt.Sprintf("%s:%s",
ec.Description,
e.ID(),
))
}
return RFCErrorCode(fmt.Sprintf("%s:%s:%s",
reg.Name,
return RFCErrorCode(fmt.Sprintf("%s:%s",
ec.Description,
e.ID(),
))
))
}

// ID returns the ID of this error.
Expand Down Expand Up @@ -278,9 +269,8 @@ func (e *Error) UnmarshalJSON(data []byte) error {
return Trace(err)
}
codes := strings.Split(string(err.RFCCode), ":")
regName := codes[0]
className := codes[1]
innerCode := codes[2]
className := codes[0]
innerCode := codes[1]
if i, errAtoi := strconv.Atoi(innerCode); errAtoi == nil {
e.code = ErrCode(i)
} else {
Expand All @@ -292,7 +282,6 @@ func (e *Error) UnmarshalJSON(data []byte) error {
e.class = &ErrClass{
Description: className,
ID: err.Class,
registry: &Registry{Name: regName},
}
return nil
}
Expand Down
10 changes: 0 additions & 10 deletions terror_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,6 @@ func (ec *ErrClass) exportTo(writer io.Writer) error {
return nil
}

// ExportTo export the registry to a writer, as toml format from the RFC.
func (r *Registry) ExportTo(writer io.Writer) error {
for _, ec := range r.errClasses {
if err := ec.exportTo(writer); err != nil {
return err
}
}
return nil
}

// CPP printf flag with minimal support for explicit argument indexes.
// introductory % character: %
// (optional) one or more flags that modify the behavior of the conversion: [+\-# 0]?
Expand Down
40 changes: 4 additions & 36 deletions terror_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ import (
"fmt"
)

// Registry is a set of errors for a component.
type Registry struct {
Name string
errClasses map[ErrClassID]ErrClass
}

// ErrCode represents a specific error type in a error class.
// Same error code can be used in different error classes.
Expand All @@ -36,43 +31,26 @@ type ErrClass struct {
ID ErrClassID
Description string
errors map[ErrorID]*Error
registry *Registry
}

type ErrorID string
type ErrClassID int
type RFCErrorCode string

// NewRegistry make a registry, where ErrClasses register to.
// One component should create only one registry, named by the RFC.
// For TiDB ecosystem components, when creating registry,
// please use the component name to name the registry, see below example:
//
// TiKV: KV
// PD: PD
// DM: DM
// BR: BR
// TiCDC: CDC
// Lightning: LN
// TiFlash: FLASH
// Dumpling: DP
func NewRegistry(name string) *Registry {
return &Registry{Name: name, errClasses: map[ErrClassID]ErrClass{}}
}
var errClasses = make(map[ErrClassID]ErrClass)

// RegisterErrorClass registers new error class for terror.
func (r *Registry) RegisterErrorClass(classCode int, desc string) ErrClass {
func RegisterErrorClass(classCode int, desc string) ErrClass {
code := ErrClassID(classCode)
if _, exists := r.errClasses[code]; exists {
if _, exists := errClasses[code]; exists {
panic(fmt.Sprintf("duplicate register ClassCode %d - %s", code, desc))
}
errClass := ErrClass{
ID: code,
Description: desc,
errors: map[ErrorID]*Error{},
registry: r,
}
r.errClasses[code] = errClass
errClasses[code] = errClass
return errClass
}

Expand Down Expand Up @@ -153,16 +131,6 @@ func (ec *ErrClass) AllErrors() []*Error {
return all
}

// AllErrorClasses returns all errClasses that has been registered.
// Note this isn't thread-safe.
func (r *Registry) AllErrorClasses() []ErrClass {
all := make([]ErrClass, 0, len(r.errClasses))
for _, errClass := range r.errClasses {
all = append(all, errClass)
}
return all
}

// Synthesize synthesizes an *Error in the air
// it didn't register error into ErrClass
// so it's goroutine-safe
Expand Down
97 changes: 17 additions & 80 deletions terror_test/terror_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@
package terror_test

import (
"bytes"
"encoding/json"
"fmt"
"os"
"runtime"
"sort"
"strings"
"testing"
"time"
Expand All @@ -32,14 +30,13 @@ import (
// Those fields below are copied from the original version of terror,
// so that we can reuse those test cases.
var (
reg = errors.NewRegistry("DB")
ClassExecutor = reg.RegisterErrorClass(5, "executor")
ClassKV = reg.RegisterErrorClass(8, "kv")
ClassOptimizer = reg.RegisterErrorClass(10, "planner")
ClassParser = reg.RegisterErrorClass(11, "parser")
ClassServer = reg.RegisterErrorClass(15, "server")
ClassTable = reg.RegisterErrorClass(19, "table")
ClassMember = reg.RegisterErrorClass(20, "member")
ClassExecutor = errors.RegisterErrorClass(5, "executor")
ClassKV = errors.RegisterErrorClass(8, "kv")
ClassOptimizer = errors.RegisterErrorClass(10, "planner")
ClassParser = errors.RegisterErrorClass(11, "parser")
ClassServer = errors.RegisterErrorClass(15, "server")
ClassTable = errors.RegisterErrorClass(19, "table")
ClassMember = errors.RegisterErrorClass(20, "member")
)

const (
Expand Down Expand Up @@ -89,7 +86,7 @@ func (s *testTErrorSuite) TestTError(c *C) {
kvErr := ClassKV.New(1062, "key already exist")
e := kvErr.FastGen("Duplicate entry '%d' for key 'PRIMARY'", 1)
c.Assert(e, NotNil)
c.Assert(e.Error(), Equals, "[DB:kv:1062] Duplicate entry '1' for key 'PRIMARY'")
c.Assert(e.Error(), Equals, "[kv:1062] Duplicate entry '1' for key 'PRIMARY'")
}

func (s *testTErrorSuite) TestJson(c *C) {
Expand Down Expand Up @@ -182,26 +179,7 @@ func (s *testTErrorSuite) TestNewError(c *C) {
today := time.Now().Weekday().String()
err := predefinedTextualErr.GenWithStackByArgs(today)
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "[DB:executor:ExecutorAbsent] executor is taking vacation at "+today)
}

func (s *testTErrorSuite) TestAllErrClasses(c *C) {
items := []errors.ErrClass{
ClassExecutor, ClassKV, ClassOptimizer, ClassParser, ClassServer, ClassTable,
}
registered := reg.AllErrorClasses()

// sort it to align them.
sort.Slice(items, func(i, j int) bool {
return items[i].ID < items[j].ID
})
sort.Slice(registered, func(i, j int) bool {
return registered[i].ID < registered[j].ID
})

for i := range items {
c.Assert(items[i].ID, Equals, registered[i].ID)
}
c.Assert(err.Error(), Equals, "[executor:ExecutorAbsent] executor is taking vacation at "+today)
}

func (s *testTErrorSuite) TestErrorExists(c *C) {
Expand Down Expand Up @@ -240,9 +218,8 @@ func (s *testTErrorSuite) TestErrorExists(c *C) {
}

func (s *testTErrorSuite) TestRFCCode(c *C) {
reg := errors.NewRegistry("TEST")
errc1 := reg.RegisterErrorClass(1, "TestErr1")
errc2 := reg.RegisterErrorClass(2, "TestErr2")
errc1 := errors.RegisterErrorClass(1, "TestErr1")
errc2 := errors.RegisterErrorClass(2, "TestErr2")
c1err1 := errc1.DefineError().
TextualCode("Err1").
MessageTemplate("nothing").
Expand All @@ -251,10 +228,9 @@ func (s *testTErrorSuite) TestRFCCode(c *C) {
TextualCode("Err2").
MessageTemplate("nothing").
Build()
c.Assert(c1err1.RFCCode(), Equals, errors.RFCErrorCode("TEST:TestErr1:Err1"))
c.Assert(c2err2.RFCCode(), Equals, errors.RFCErrorCode("TEST:TestErr2:Err2"))
blankReg := errors.NewRegistry("")
errb := blankReg.RegisterErrorClass(1, "Blank")
c.Assert(c1err1.RFCCode(), Equals, errors.RFCErrorCode("TestErr1:Err1"))
c.Assert(c2err2.RFCCode(), Equals, errors.RFCErrorCode("TestErr2:Err2"))
errb := errors.RegisterErrorClass(3, "Blank")
berr := errb.DefineError().
TextualCode("B1").
MessageTemplate("nothing").
Expand Down Expand Up @@ -284,45 +260,6 @@ workaround = '''Check the status, monitoring data and log of the TiKV server.'''
`
)

func (*testTErrorSuite) TestExport(c *C) {
RegKV := errors.NewRegistry("KV")
Class2PC := RegKV.RegisterErrorClass(1, "2PC")
_ = Class2PC.DefineError().
NumericCode(8005).
Description("A certain Raft Group is not available, such as the number of replicas is not enough.\n" +
"This error usually occurs when the TiKV server is busy or the TiKV node is down.").
Workaround("Check whether `tidb_disable_txn_auto_retry` is set to `on`. If so, set it to `off`; " +
"if it is already `off`, increase the value of `tidb_retry_limit` until the error no longer occurs.").
MessageTemplate("Write Conflict, txnStartTS is stale").
Build()

ClassRegion := RegKV.RegisterErrorClass(2, "Region")
_ = ClassRegion.DefineError().
TextualCode("Unavailable").
Description("A certain Raft Group is not available, such as the number of replicas is not enough.\n" +
"This error usually occurs when the TiKV server is busy or the TiKV node is down.").
Workaround("Check the status, monitoring data and log of the TiKV server.").
MessageTemplate("Region is unavailable").
Build()

ClassSomewhat := RegKV.RegisterErrorClass(3, "Somewhat")
_ = ClassSomewhat.DefineError().
TextualCode("Foo").
MessageTemplate("some %.6s thing happened, and some %#v goes verbose. I'm %6.3f percent confusing...\n" +
"Maybe only %[3]*.[2]*[1]f peaces of placeholders can save me... Oh my %s.%d!").
Build()

result := bytes.NewBuffer([]byte{})
err := RegKV.ExportTo(result)
c.Assert(err, IsNil)
resultStr := result.String()
fmt.Println("Result: ")
fmt.Print(resultStr)
c.Assert(strings.Contains(resultStr, somewhatErrorTOML), IsTrue)
c.Assert(strings.Contains(resultStr, err8005TOML), IsTrue)
c.Assert(strings.Contains(resultStr, errUnavailableTOML), IsTrue)
}

func (*testTErrorSuite) TestLineAndFile(c *C) {
err := predefinedTextualErr.GenWithStackByArgs("everyday")
_, f, l, _ := runtime.Caller(0)
Expand All @@ -344,7 +281,7 @@ func (*testTErrorSuite) TestLineAndFile(c *C) {
func (*testTErrorSuite) TestWarpAndField(c *C) {
causeErr := errors.New("load from etcd meet error")
ErrGetLeader := ClassMember.DefineError().TextualCode("ErrGetLeader").MessageTemplate("fail to get leader").Build()
errWithWarpedCause := ErrGetLeader.WarpCauseError(causeErr)
c.Assert(errWithWarpedCause.FastGenWithCause().Error(), Equals, "[DB:member:ErrGetLeader] load from etcd meet error")
c.Assert(fmt.Sprintf("%v", errWithWarpedCause.FastGenWithCause()), Equals, "[DB:member:ErrGetLeader] fail to get leader")
errWithWarpedCause := ErrGetLeader.Wrap(causeErr)
c.Assert(errWithWarpedCause.FastGenWithCause().Error(), Equals, "[member:ErrGetLeader] load from etcd meet error")
c.Assert(fmt.Sprintf("%v", errWithWarpedCause.FastGenWithCause()), Equals, "[member:ErrGetLeader] fail to get leader")
}

0 comments on commit 831d046

Please sign in to comment.