github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/meta/error.go (about) 1 /** 2 * Copyright 2023 CloudWeGo Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package meta 18 19 import ( 20 "fmt" 21 "strings" 22 ) 23 24 // CategoryBitOnErrorCode is used to shift category on error code 25 const CategoryBitOnErrorCode = 24 26 27 // ErrCode is the error code of dynamicgo. 28 // Usually the left 8 bits are used to represent the category of error, 29 // and the right 24 bits are used to represent the behavior of error. 30 type ErrCode uint32 31 32 // Error Behaviors 33 const ( 34 // ErrUnsupportedType represents unsupported type error 35 ErrUnsupportedType ErrCode = 1 + iota 36 // ErrStackOverflow represents exceed stack limit error 37 ErrStackOverflow 38 // ErrRead represents read error 39 ErrRead 40 // ErrWrite represents write error 41 ErrWrite 42 // ErrDismatchType represents dismatch type error 43 ErrDismatchType 44 // ErrConvert represents convert error 45 ErrConvert 46 // ErrNotFound represents not found error 47 ErrNotFound 48 // ErrMissRequiredField represents missing required field error 49 ErrMissRequiredField 50 // ErrUnknownField represents unknown field error 51 ErrUnknownField 52 // ErrInvalidParam represents invalid parameter error 53 ErrInvalidParam 54 // ErrNotImplemented represents not implemented error 55 ErrNotImplemented 56 ) 57 58 var errsMap = map[ErrCode]string{ 59 ErrUnsupportedType: "unsupported type", 60 ErrStackOverflow: "exceed depth limit", 61 ErrRead: "read failed", 62 ErrWrite: "write failed", 63 ErrDismatchType: "dismatched type", 64 ErrConvert: "convert failed", 65 ErrNotFound: "not found", 66 ErrMissRequiredField: "missing required field", 67 ErrUnknownField: "unknown field", 68 ErrInvalidParam: "invalid parameter", 69 } 70 71 // NewErrorCode created a new error code with category and behavior 72 func NewErrorCode(behavior ErrCode, category Category) ErrCode { 73 return behavior | (ErrCode(category) << CategoryBitOnErrorCode) 74 } 75 76 // Category returns the category of error code 77 func (ec ErrCode) Category() Category { 78 return Category(ec >> CategoryBitOnErrorCode) 79 } 80 81 // String returns the string representation of error code 82 func (ec ErrCode) String() string { 83 if m, ok := errsMap[ec.Behavior()]; ok { 84 return m 85 } else { 86 return fmt.Sprintf("error code %d", ec) 87 } 88 } 89 90 // Error implement error interface 91 func (ec ErrCode) Error() string { 92 return ec.String() 93 } 94 95 // Behavior returns the behavior of error code 96 func (ec ErrCode) Behavior() ErrCode { 97 return ErrCode(ec & 0x00ffffff) 98 } 99 100 // Error is the error concrete type of dynamicgo 101 type Error struct { 102 Code ErrCode 103 Msg string 104 Err error 105 } 106 107 // NewError creates a new error with error code, message and preceding error 108 // 109 //go:noinline 110 func NewError(code ErrCode, msg string, err error) error { 111 return Error{ 112 Code: code, 113 Msg: msg, 114 Err: err, 115 } 116 } 117 118 // Message return current message if has, 119 // otherwise return preceding error message 120 func (err Error) Message() string { 121 output := []string{err.Msg} 122 if err.Err != nil { 123 output = append(output, err.Err.Error()) 124 } 125 return strings.Join(output, "\n") 126 } 127 128 // Error return error message, 129 // combining category, behavior and message 130 func (err Error) Error() string { 131 return fmt.Sprintf("[%s] %s: %s", err.Code.Category(), err.Code.Behavior(), err.Message()) 132 } 133 134 // Unwrap implements errors.Unwrap interface 135 func (err Error) Unwrap() error { 136 return err.Err 137 }