feat: error wrapper
This commit is contained in:
parent
a8310b5dc8
commit
d92cace9c8
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/errors.iml" filepath="$PROJECT_DIR$/.idea/errors.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1 @@
|
|||
golang 1.16
|
|
@ -0,0 +1,131 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestManual(t *testing.T) {
|
||||
t.Logf("default: %v\n", NewError())
|
||||
|
||||
}
|
||||
|
||||
func TestNeedExit(t *testing.T) {
|
||||
type args struct {
|
||||
err error
|
||||
}
|
||||
|
||||
simpleCaseErr := NewError()
|
||||
CaseNoExitErr := NewError().SetExitStatus(0)
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want ErrorWithStatus
|
||||
want1 bool
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
args: args{
|
||||
err: simpleCaseErr,
|
||||
},
|
||||
want: simpleCaseErr,
|
||||
want1: true,
|
||||
},
|
||||
{
|
||||
name: "nil input",
|
||||
args: args{
|
||||
err: nil,
|
||||
},
|
||||
want: nil,
|
||||
want1: false,
|
||||
},
|
||||
{
|
||||
name: "not ErrorWithStatus",
|
||||
args: args{
|
||||
err: errors.New("test"),
|
||||
},
|
||||
want: nil,
|
||||
want1: false,
|
||||
},
|
||||
{
|
||||
name: "error but no exit",
|
||||
args: args{
|
||||
err: CaseNoExitErr,
|
||||
},
|
||||
want: CaseNoExitErr,
|
||||
want1: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, got1 := NeedExit(tt.args.err)
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("NeedExit() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
if got1 != tt.want1 {
|
||||
t.Errorf("NeedExit() got1 = %v, want %v", got1, tt.want1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewErrorWithFrames(t *testing.T) {
|
||||
type args struct {
|
||||
err error
|
||||
}
|
||||
|
||||
simplecase := errors.New("test")
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want ErrorWithStatus
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{
|
||||
name: "simple",
|
||||
args: args{
|
||||
err: simplecase,
|
||||
},
|
||||
want: NewErrorWithFrames(simplecase),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := NewErrorWithFrames(tt.args.err); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("NewErrorWithFrames() = %v, want %v", got, tt.want)
|
||||
} else {
|
||||
t.Log("check", got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue