瀏覽代碼

feat: 版本1

SongZihuan 1 年之前
當前提交
b192819eb3
共有 7 個文件被更改,包括 197 次插入0 次删除
  1. 7 0
      .gitignore
  2. 96 0
      errors.go
  3. 12 0
      errors_test.go
  4. 3 0
      go.mod
  5. 18 0
      reflect.go
  6. 9 0
      stack.go
  7. 52 0
      utils.go

+ 7 - 0
.gitignore

@@ -0,0 +1,7 @@
+.idea
+etc
+tmp
+cert
+
+*.exe
+*.out

+ 96 - 0
errors.go

@@ -0,0 +1,96 @@
+package errors
+
+import (
+	"errors"
+	"fmt"
+)
+
+const UnknownError = "UNKNOWN"
+
+type WTError interface {
+	/* 标记类操作 */
+	error
+	WTError() // 标记
+
+	/* 访问类操作 */
+	Code() string
+	Message() string
+	Stack() string
+	Cause() error
+
+	/* 设置类操作 */
+	SetCode(code string) WTError
+	SetCodeForce(code string) WTError
+	SetCause(cause error) WTError
+	SetCauseForce(cause error) WTError
+	Warp(format string, a ...any) WTError
+}
+
+type wtError struct {
+	cause error
+	msg   string
+	code  string
+	stack string
+}
+
+func (*wtError) WTError() {}
+
+func (w *wtError) Code() string {
+	return w.code
+}
+
+func (w *wtError) Message() string {
+	if w.cause == nil {
+		return fmt.Sprintf("[%s] %s", w.code, w.msg)
+	}
+
+	var cause *wtError
+	ok := errors.As(w.cause, &cause)
+	if ok {
+		return fmt.Sprintf("[%s] %s: %s", w.code, w.msg, cause.Message())
+	}
+
+	return fmt.Sprintf("[%s] %s: %s", w.code, w.msg, w.cause.Error())
+}
+
+func (w *wtError) Stack() string {
+	return w.stack
+}
+
+func (w *wtError) Error() string {
+	return w.Message()
+}
+
+func (w *wtError) Cause() error {
+	return w.cause
+}
+
+func (w *wtError) SetCode(code string) WTError {
+	if w.code == UnknownError {
+		w.code = code
+	}
+	return w
+}
+
+func (w *wtError) SetCodeForce(code string) WTError {
+	w.code = code
+	return w
+}
+
+func (w *wtError) SetCause(cause error) WTError {
+	if w.cause == nil {
+		w.cause = cause
+		_ = w.SetCode(getErrorName(cause))
+	}
+	return w
+}
+
+func (w *wtError) SetCauseForce(cause error) WTError {
+	w.cause = cause
+	_ = w.SetCode(getErrorName(cause))
+	return w
+}
+
+func (w *wtError) Warp(format string, a ...any) WTError {
+	return Warp(w, format, a...)
+}

+ 12 - 0
errors_test.go

@@ -0,0 +1,12 @@
+package errors
+
+import "testing"
+
+func TestIs(t *testing.T) {
+	err := Errorf("New error: %d", 10)
+	_ = err.SetCode("Code")
+
+	if err.Code() != "Code" {
+		t.Errorf("Error code is not set")
+	}
+}

+ 3 - 0
go.mod

@@ -0,0 +1,3 @@
+module wterrors
+
+go 1.21

+ 18 - 0
reflect.go

@@ -0,0 +1,18 @@
+package errors
+
+import "reflect"
+
+func getErrorName(err error) string {
+	t := reflect.TypeOf(err)
+	if t.Kind() == reflect.Invalid {
+		return UnknownError
+	}
+
+	for {
+		if t.Kind() == reflect.Ptr || t.Kind() == reflect.Interface {
+			t = t.Elem()
+		} else {
+			return t.Name()
+		}
+	}
+}

+ 9 - 0
stack.go

@@ -0,0 +1,9 @@
+package errors
+
+import "runtime"
+
+func getStack() string {
+	buf := make([]byte, 1024)
+	n := runtime.Stack(buf, false)
+	return string(buf[:n])
+}

+ 52 - 0
utils.go

@@ -0,0 +1,52 @@
+package errors
+
+import (
+	"errors"
+	"fmt"
+)
+
+func Errorf(format string, a ...any) WTError {
+	msg := fmt.Sprintf(format, a...)
+	code := UnknownError
+	cause := error(nil)
+	stack := getStack()
+
+	return &wtError{
+		cause: cause,
+		msg:   msg,
+		code:  code,
+		stack: stack,
+	}
+}
+
+func Warp(err error, format string, a ...any) WTError {
+	msg := fmt.Sprintf(format, a...)
+	code := UnknownError
+	cause := err
+	stack := getStack()
+
+	return &wtError{
+		cause: cause,
+		msg:   msg,
+		code:  code,
+		stack: stack,
+	}
+}
+
+func Is(err error, target error) bool {
+	var wtErr, wtTarget WTError
+
+	if errors.As(err, &wtErr) && errors.As(target, &wtTarget) {
+		if wtErr.Code() == wtTarget.Code() {
+			return true
+		} else if wtErr == wtTarget {
+			return true
+		}
+	}
+
+	return errors.Is(err, target)
+}
+
+func As(err error, target any) bool {
+	return errors.As(err, target)
+}