improve errcode feature for package gerror

This commit is contained in:
John Guo
2021-08-04 20:50:45 +08:00
parent ff70e54e3e
commit 4c54b1cfbc
8 changed files with 122 additions and 42 deletions

View File

@ -142,10 +142,14 @@ func WrapSkipf(skip int, err error, format string, args ...interface{}) error {
}
// NewCode creates and returns an error that has error code and given text.
func NewCode(code int, text string) error {
func NewCode(code int, text ...string) error {
errText := ""
if len(text) > 0 {
errText = text[0]
}
return &Error{
stack: callers(),
text: text,
text: errText,
code: code,
}
}
@ -238,14 +242,24 @@ func WrapCodeSkipf(code, skip int, err error, format string, args ...interface{}
}
// Code returns the error code of current error.
// It returns -1 if it has no error code or it does not implements interface Code.
// It returns CodeNil if it has no error code or it does not implements interface Code.
func Code(err error) int {
if err != nil {
if e, ok := err.(apiCode); ok {
return e.Code()
}
}
return -1
return CodeNil
}
// CodeMessage retrieves and returns the error code message from given error.
func CodeMessage(err error) string {
return Message(Code(err))
}
// Message returns the message string for specified code.
func Message(code int) string {
return codeMessageMap[code]
}
// Cause returns the root cause error of <err>.

View File

@ -9,32 +9,60 @@ package gerror
// Reserved internal error code of framework: code < 1000.
const (
// ===============================================================================
// Common system codes.
// ===============================================================================
CodeNil = -1 // No error code specified.
CodeOk = 0 // It is OK.
CodeInternalError = 50 + iota // An error occurred internally.
CodeValidationFailed // Data validation failed.
CodeDbOperationError // Database operation error.
CodeInvalidParameter // The given parameter for current operation is invalid.
CodeMissingParameter // Parameter for current operation is missing.
CodeInvalidOperation // The function cannot be used like this.
CodeInvalidConfiguration // The configuration is invalid for current operation.
CodeMissingConfiguration // The configuration is missing for current operation.
CodeNotImplemented // The operation is not implemented yet.
CodeNotSupported // The operation is not supported yet.
CodeOperationFailed // I tried, but I cannot give you what you want.
CodeNotAuthorized // Not Authorized.
CodeSecurityReason // Security Reason.
CodeServerBusy // Server is busy, please try again later.
CodeUnknown // Unknown error.
CodeResourceNotExist // Resource does not exist.
// ===============================================================================
// Common business codes.
// ===============================================================================
CodeBusinessValidationFailed = 300 + iota // Business validation failed.
CodeNil = -1 // No error code specified.
CodeOk = 0 // It is OK.
CodeInternalError = 50 // An error occurred internally.
CodeValidationFailed = 51 // Data validation failed.
CodeDbOperationError = 52 // Database operation error.
CodeInvalidParameter = 53 // The given parameter for current operation is invalid.
CodeMissingParameter = 54 // Parameter for current operation is missing.
CodeInvalidOperation = 55 // The function cannot be used like this.
CodeInvalidConfiguration = 56 // The configuration is invalid for current operation.
CodeMissingConfiguration = 57 // The configuration is missing for current operation.
CodeNotImplemented = 58 // The operation is not implemented yet.
CodeNotSupported = 59 // The operation is not supported yet.
CodeOperationFailed = 60 // I tried, but I cannot give you what you want.
CodeNotAuthorized = 61 // Not Authorized.
CodeSecurityReason = 62 // Security Reason.
CodeServerBusy = 63 // Server is busy, please try again later.
CodeUnknown = 64 // Unknown error.
CodeResourceNotExist = 65 // Resource does not exist.
CodeBusinessValidationFailed = 300 // Business validation failed.
)
var (
// codeMessageMap is the mapping from code to according string message.
codeMessageMap = map[int]string{
CodeNil: "",
CodeOk: "OK",
CodeInternalError: "Internal Error",
CodeValidationFailed: "Validation Failed",
CodeDbOperationError: "Database Operation Error",
CodeInvalidParameter: "Invalid Parameter",
CodeMissingParameter: "Missing Parameter",
CodeInvalidOperation: "Invalid Operation",
CodeInvalidConfiguration: "Invalid Configuration",
CodeMissingConfiguration: "Missing Configuration",
CodeNotImplemented: "Not Implemented",
CodeNotSupported: "Not Supported",
CodeOperationFailed: "Operation Failed",
CodeNotAuthorized: "Not Authorized",
CodeSecurityReason: "Security Reason",
CodeServerBusy: "Server Is Busy",
CodeUnknown: "Unknown Error",
CodeResourceNotExist: "Resource Not Exist",
CodeBusinessValidationFailed: "Business Validation Failed",
}
)
// RegisterCode registers custom error code to global error codes for gerror recognition.
func RegisterCode(code int, message string) {
codeMessageMap[code] = message
}
// RegisterCodeMap registers custom error codes to global error codes for gerror recognition using map.
func RegisterCodeMap(codes map[int]string) {
for k, v := range codes {
codeMessageMap[k] = v
}
}

View File

@ -57,10 +57,10 @@ func (err *Error) Error() string {
}
// Code returns the error code.
// It returns -1 if it has no error code.
// It returns CodeNil if it has no error code.
func (err *Error) Code() int {
if err == nil {
return -1
return CodeNil
}
return err.code
}
@ -159,6 +159,7 @@ func (err *Error) Current() error {
error: nil,
stack: err.stack,
text: err.text,
code: err.code,
}
}

View File

@ -261,8 +261,8 @@ func Test_Code(t *testing.T) {
t.Assert(err.Error(), "123")
})
gtest.C(t, func(t *gtest.T) {
err := gerror.NewCode(1, "123")
t.Assert(gerror.Code(err), 1)
err := gerror.NewCode(gerror.CodeUnknown, "123")
t.Assert(gerror.Code(err), gerror.CodeUnknown)
t.Assert(err.Error(), "123")
})
gtest.C(t, func(t *gtest.T) {
@ -318,3 +318,36 @@ func Test_Json(t *testing.T) {
t.Assert(string(b), `"2: 1"`)
})
}
func Test_Message(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
t.Assert(gerror.Message(-100), ``)
t.Assert(gerror.Message(gerror.CodeNil), ``)
t.Assert(gerror.Message(gerror.CodeOk), `OK`)
})
}
func Test_CodeMessage(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
err := gerror.NewCode(gerror.CodeUnknown)
t.Assert(gerror.CodeMessage(err), `Unknown Error`)
})
}
func Test_RegisterCode(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
gerror.RegisterCode(10086, "MobileTelecom")
t.Assert(gerror.Message(10086), `MobileTelecom`)
})
}
func Test_RegisterCodeMap(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
gerror.RegisterCodeMap(map[int]string{
10087: "MobileTelecom 10087",
10088: "MobileTelecom 10088",
})
t.Assert(gerror.Message(10087), `MobileTelecom 10087`)
t.Assert(gerror.Message(10088), `MobileTelecom 10088`)
})
}