pink_fox/application/packages/fw/error.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)
}
}