errors/errors.go

132 lines
2.4 KiB
Go

package errors
import (
"errors"
"fmt"
"runtime"
)
type ErrorWithStatus interface {
error
ExitStatus() int
IsSkipPrintMessage() bool
SetError(err error) ErrorWithStatus
SkipMessage() ErrorWithStatus
SetPrintMessage() ErrorWithStatus
SetExitStatus(status int) ErrorWithStatus
}
type errorWithStatus struct {
err error
status int
skipMessage bool
frames []frame
}
type frame struct {
file string
line int
function string
}
func NeedExit(err error) (ErrorWithStatus, bool) {
if err != nil {
if esw, ok := err.(ErrorWithStatus); ok {
return esw, esw.ExitStatus() != 0
}
}
return nil, false
}
func NewErrorWithStatus(err error, status int, skipMessage bool) ErrorWithStatus {
return &errorWithStatus{
err: err,
status: status,
skipMessage: skipMessage,
}
}
func NewError() ErrorWithStatus {
return &errorWithStatus{
err: errors.New("error"),
status: -1,
skipMessage: false,
}
}
func NewErrorWithFrames(err error) ErrorWithStatus {
pcs := make([]uintptr, 0)
npc := runtime.Callers(0, pcs)
returnValue := &errorWithStatus{
err: err,
status: -1,
skipMessage: false,
}
if npc > 0 {
frs := runtime.CallersFrames(pcs)
more := true
var fr runtime.Frame
for more {
fr, more = frs.Next()
returnValue.frames = append(returnValue.frames, frame{
file: fr.File,
function: fr.Function,
line: fr.Line,
})
}
}
return returnValue
}
func NewErrorfStatus(status int, str string, v ...interface{}) ErrorWithStatus {
return &errorWithStatus{
err: fmt.Errorf(str, v...),
status: status,
skipMessage: false,
}
}
func NewErrorf(str string, v ...interface{}) ErrorWithStatus {
return NewErrorfStatus(-1, str, v...)
}
func (e *errorWithStatus) Error() string {
var s string
for _, fr := range e.frames {
s += fmt.Sprintf("\n%v", fr)
}
return e.err.Error() + s
}
func (e *errorWithStatus) ExitStatus() int {
return e.status
}
func (e *errorWithStatus) IsSkipPrintMessage() bool {
return e.skipMessage
}
func (e *errorWithStatus) SetError(err error) ErrorWithStatus {
e.err = err
return e
}
func (e *errorWithStatus) SkipMessage() ErrorWithStatus {
e.skipMessage = true
return e
}
func (e *errorWithStatus) SetPrintMessage() ErrorWithStatus {
e.skipMessage = false
return e
}
func (e *errorWithStatus) SetExitStatus(status int) ErrorWithStatus {
e.status = status
return e
}