diff --git a/abstrace.go b/abstrace.go index 186e077..60fb7e0 100644 --- a/abstrace.go +++ b/abstrace.go @@ -25,4 +25,6 @@ type IException interface { ToError() error // IsCode 是否为指定code IsCode(code any) bool + // GetStack 获取调用堆栈 + GetStack() string } diff --git a/code.go b/code.go index ba36ea3..b9804fd 100644 --- a/code.go +++ b/code.go @@ -82,7 +82,7 @@ var ( // messageWithCode 自动在message文案后追加状态码 messageWithCode = true // defaultSuccessCode 默认代表成功的状态码 - defaultSuccessCode any + defaultSuccessCode any = 0 // defaultLanguage 默认的语言 defaultLanguage = "zh" ) diff --git a/exception.go b/exception.go index e940595..a9bbe5a 100644 --- a/exception.go +++ b/exception.go @@ -10,6 +10,9 @@ package exception import ( "errors" "fmt" + "runtime" + "strconv" + "strings" ) // Exception 异常接口的具体实现 @@ -21,12 +24,17 @@ type Exception struct { code any message string data map[string]any + stack string } func (e *Exception) Error() string { return e.Message() } +func (e *Exception) GetStack() string { + return e.stack +} + func (e *Exception) Code() any { return e.code } @@ -83,10 +91,29 @@ func New(code any, data map[string]any, defaultMessage ...string) IException { // 保证数据结构的一致性, 同时避免后续使用出现空指针 data = map[string]any{} } + pcs := make([]uintptr, 128) + n := runtime.Callers(2, pcs) + frames := runtime.CallersFrames(pcs[:n]) + var sb strings.Builder + for { + frame, more := frames.Next() + sb.WriteString(frame.Function) + sb.WriteByte('\n') + sb.WriteByte('\t') + sb.WriteString(frame.File) + sb.WriteByte(':') + sb.WriteString(strconv.Itoa(frame.Line)) + sb.WriteByte('\n') + + if !more { + break + } + } return &Exception{ code: code, message: GetMessage(code, defaultMessage...), data: data, + stack: sb.String(), } }