132 lines
2.4 KiB
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
|
|
}
|