Add Trace function

This commit is contained in:
Nicolas JUHEL
2020-05-11 15:55:57 +02:00
parent f7285757fb
commit 9b4f2aa888
2 changed files with 101 additions and 14 deletions

View File

@@ -25,22 +25,29 @@
package njs_errors
import "fmt"
import (
"fmt"
"path"
"runtime"
"strings"
)
type ErrorCode interface {
Error() error
ErrorWithCode() error
ErrorFull() error
String() string
StringWithCode() string
StringFull() string
Code() string
Trace() runtime.Frame
}
type errorCode struct {
code string
err ErrorType
ori error
trace runtime.Frame
}
// Error return an error type of the current error code, with no code in reference
@@ -58,12 +65,38 @@ func (e errorCode) Code() string {
return e.code
}
// ErrorWithCode return a error type of the current code, with error and origin in reference
func (e errorCode) StringWithCode() string {
return e.ErrorWithCode().Error()
// Trace return a runtime frame of the current error
func (e errorCode) Trace() runtime.Frame {
return e.trace
}
// ErrorWithCode return a error type of the current code, with error and origin in reference
func (e errorCode) ErrorWithCode() error {
func (e errorCode) StringFull() string {
return e.ErrorFull().Error()
}
// ErrorWithCode return a error type of the current code, with error and origin in reference
func (e errorCode) ErrorFull() error {
if e.trace != getNilFrame() {
var t = make([]string, 0)
if e.trace.File != "" {
t = append(t, path.Base(e.trace.File))
}
if e.trace.Function != "" {
t = append(t, e.trace.Function)
}
if e.trace.Line > 0 {
t = append(t, fmt.Sprintf("%v", e.trace.Line))
}
if len(t) > 0 {
return fmt.Errorf("(%s) [%s] %v", e.code, strings.Join(t, "|"), e.Error())
}
}
return fmt.Errorf("(%s) %v", e.code, e.Error())
}

View File

@@ -25,7 +25,17 @@
package njs_errors
var _listCodeErrors = make(map[string]ErrorType, 0)
import (
"path"
"reflect"
"runtime"
"strings"
)
var (
currPkgs = path.Base(reflect.TypeOf(ERR_UNKNOWN).PkgPath())
_listCodeErrors = make(map[string]ErrorType, 0)
)
// SetErrorCode Register a new error with code and an error string as ErrorType
func SetErrorCode(code string, err ErrorType) {
@@ -63,6 +73,18 @@ func DelAllErrorCode() {
// If the code is not found an 'ERR_UNKNOWN' will be used instead of the awaiting error
// If an origin error is given in params, this origin error will be used in the reference of generated error or string
func GetErrorCode(code string, origin error) ErrorCode {
return getErrorCode(code, origin, getNilFrame())
}
// GetTraceErrorCode return an ErrorCode interface mapped to given params code.
// If the code is not found an 'ERR_UNKNOWN' will be used instead of the awaiting error
// If an origin error is given in params, this origin error will be used in the reference of generated error or string
// This function add a trace of error generated
func GetTraceErrorCode(code string, origin error) ErrorCode {
return getErrorCode(code, origin, getFrame())
}
func getErrorCode(code string, origin error, trace runtime.Frame) ErrorCode {
var (
e ErrorType
ok bool
@@ -76,5 +98,37 @@ func GetErrorCode(code string, origin error) ErrorCode {
code: code,
err: e,
ori: origin,
trace: trace,
}
}
func getFrame() runtime.Frame {
// Set size to targetFrameIndex+2 to ensure we have room for one more caller than we need
programCounters := make([]uintptr, 0)
n := runtime.Callers(0, programCounters)
if n > 0 {
frames := runtime.CallersFrames(programCounters[:n])
more := true
for more {
var (
frame runtime.Frame
)
frame, more = frames.Next()
if strings.Contains(frame.Function, currPkgs) {
continue
}
return frame
}
}
return getNilFrame()
}
func getNilFrame() runtime.Frame {
return runtime.Frame{Function: "", File: "", Line: 0}
}