116 lines
1.9 KiB
Go
116 lines
1.9 KiB
Go
package fw
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
type Error interface {
|
|
Add(string) Error
|
|
Tap() Error
|
|
Message() string
|
|
Trace() []string
|
|
Error() string
|
|
}
|
|
|
|
type LogError struct {
|
|
err error
|
|
messages []string
|
|
trace []string
|
|
stack []byte
|
|
}
|
|
|
|
func Err(err error) *LogError {
|
|
return &LogError{
|
|
err: err,
|
|
trace: []string{trace()},
|
|
}
|
|
}
|
|
|
|
func ErrStr(msg string) *LogError {
|
|
return &LogError{
|
|
messages: []string{msg},
|
|
trace: []string{trace()},
|
|
}
|
|
}
|
|
|
|
func (it *LogError) Add(msg string) Error {
|
|
it.trace = append(it.trace, trace())
|
|
it.messages = append(it.messages, msg)
|
|
return it
|
|
}
|
|
|
|
func (it *LogError) Tap() Error {
|
|
it.trace = append(it.trace, trace())
|
|
return it
|
|
}
|
|
|
|
func (it *LogError) Message() string {
|
|
result := ""
|
|
for i := len(it.messages) - 1; i >= 0; i-- {
|
|
if result == "" {
|
|
result += fmt.Sprintf("%v", it.messages[i])
|
|
} else {
|
|
result += fmt.Sprintf(": %v", it.messages[i])
|
|
}
|
|
}
|
|
if it.err != nil {
|
|
if result == "" {
|
|
result += fmt.Sprintf("%v", it.err)
|
|
} else {
|
|
result += fmt.Sprintf(": %v", it.err)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (it *LogError) Error() string {
|
|
result := ""
|
|
if len(it.trace) > 0 {
|
|
result = "\n\t" + strings.Join(it.trace, "\n\t")
|
|
}
|
|
return it.Message() + result
|
|
}
|
|
|
|
func (it *LogError) Trace() []string {
|
|
return it.trace
|
|
}
|
|
|
|
type PanicError struct {
|
|
*LogError
|
|
}
|
|
|
|
func ErrPanic(err error, stack []byte) *PanicError {
|
|
e := PanicError{
|
|
LogError: Err(err),
|
|
}
|
|
e.trace = strings.Split(string(stack), "\n")
|
|
return &e
|
|
}
|
|
|
|
var (
|
|
basePath = "packages/fw/error.go"
|
|
)
|
|
|
|
func init() {
|
|
_, file, _, ok := runtime.Caller(0)
|
|
if !ok {
|
|
return
|
|
}
|
|
basePath = file[:len(file)-len(basePath)]
|
|
}
|
|
|
|
func trace() string {
|
|
_, file, line, ok := runtime.Caller(2)
|
|
if !ok {
|
|
return "it was not possible to recover the information"
|
|
}
|
|
|
|
if strings.HasPrefix(file, basePath) {
|
|
return fmt.Sprintf("%s:%d", file[len(basePath):], line)
|
|
} else {
|
|
return fmt.Sprintf("%s:%d", file, line)
|
|
}
|
|
}
|