Files
v2ray_simple/utils/error.go
T
2023-02-12 11:38:03 +08:00

180 lines
3.3 KiB
Go

package utils
import (
"bytes"
"errors"
"fmt"
"strconv"
"strings"
)
var (
ErrUnImplemented = errors.New("not implemented")
ErrNilParameter = errors.New("nil parameter")
ErrNilOrWrongParameter = errors.New("nil or wrong parameter")
ErrWrongParameter = errors.New("wrong parameter")
ErrInvalidData = errors.New("invalid data")
ErrNoMatch = errors.New("no matched")
ErrInvalidNumber = errors.New("invalid number")
ErrInvalidWrite = errors.New("readfrom, invalid write result")
ErrShortRead = errors.New("short read") //io包有ErrShortWrite,却没有ShortRead
ErrHandled = errors.New("handled")
ErrFailed = errors.New("failed") //最无脑的Err, 在能描述清楚错误时不要使用 ErrFailed
)
type InvalidDataErr string
// return err == e || err == ErrInvalidData
func (e InvalidDataErr) Is(err error) bool {
return err == e || err == ErrInvalidData
}
func (e InvalidDataErr) Error() string {
return string(e)
}
// nothing special. Normally, N==0 means no error
type NumErr struct {
N int
E error
}
func (ne NumErr) Error() string {
return ne.E.Error() + ", " + strconv.Itoa(ne.N)
}
func (e NumErr) Is(target error) bool {
return errors.Is(e.E, target)
}
func (ef NumErr) Unwarp() error {
return ef.E
}
// nothing special
type NumStrErr struct {
N int
Prefix string
}
func (ne NumStrErr) Error() string {
return ne.Prefix + strconv.Itoa(ne.N)
}
// an err with a buffer, nothing special
type ErrBuffer struct {
Err error
Buf *bytes.Buffer
}
func (e ErrBuffer) Is(target error) bool {
return errors.Is(e.Err, target)
}
func (ef ErrBuffer) Unwarp() error {
return ef.Err
}
func (ef ErrBuffer) Error() string {
if ef.Buf != nil {
return ef.Err.Error() + ", with Buffer,len " + strconv.Itoa(ef.Buf.Len())
} else {
return ef.Err.Error() + ", with nil Buffer."
}
}
// ErrInErr 很适合一个err包含另一个err,并且提供附带数据的情况. 类似 fmt.Errorf.
type ErrInErr struct {
ErrDesc string
ErrDetail error
Data any
ExtraIs []error
}
func (e ErrInErr) Error() string {
return e.String()
}
func (e ErrInErr) Unwarp() error {
return e.ErrDetail
}
func (e ErrInErr) Is(target error) bool {
if e.ErrDetail == target {
return true
} else if errors.Is(e.ErrDetail, target) {
return true
} else if len(e.ExtraIs) > 0 {
for _, v := range e.ExtraIs {
if errors.Is(v, target) {
return true
}
}
}
return false
}
func (e ErrInErr) String() string {
if e.Data != nil {
if e.ErrDetail != nil {
return fmt.Sprintf(" [ %s , Detail: %s, Data: %v ] ", e.ErrDesc, e.ErrDetail.Error(), e.Data)
}
return fmt.Sprintf(" [ %s , Data: %v ] ", e.ErrDesc, e.Data)
}
if e.ErrDetail != nil {
return fmt.Sprintf(" [ %s , Detail: %s ] ", e.ErrDesc, e.ErrDetail.Error())
}
return e.ErrDesc
}
type Errs struct {
List []ErrsItem
}
type ErrsItem struct {
Index int
E error
}
func (ee *Errs) Add(e ErrsItem) {
ee.List = append(ee.List, e)
}
func (e Errs) OK() bool {
return len(e.List) == 0
}
func (e Errs) String() string {
var sb strings.Builder
for _, err := range e.List {
sb.WriteString(strconv.Itoa(err.Index))
sb.WriteString(", ")
if err.E != nil {
sb.WriteString(err.E.Error())
}
sb.WriteString("\n")
}
return sb.String()
}
func (e Errs) Error() string {
return e.String()
}