doc: Adjust the Chinese comments in the code to English

This commit is contained in:
dapeng 2024-06-14 22:46:00 +08:00
parent f903d8d036
commit f044933186
23 changed files with 632 additions and 305 deletions

View File

@ -185,7 +185,7 @@ func (c *cemetery) reviveFieldById(tag string, field reflect.StructField, v refl
goner := tomb.GetGoner()
if IsCompatible(field.Type, goner) {
c.setFieldValue(v, goner)
setFieldValue(v, goner)
suc = true
return
}
@ -241,7 +241,7 @@ func (c *cemetery) reviveByVampire2(goner Goner, tomb Tomb, extConfig string, v
func (c *cemetery) reviveFieldByType(field reflect.StructField, v reflect.Value, goneTypeName string) (deps []Tomb, suc bool) {
container := c.getGonerContainerByType(field.Type, fmt.Sprintf("%s.%s", goneTypeName, field.Name))
if container != nil {
c.setFieldValue(v, container.GetGoner())
setFieldValue(v, container.GetGoner())
suc = true
deps = append(deps, container)
}

View File

@ -2,9 +2,29 @@ package gone
import (
"fmt"
"net/http"
"reflect"
)
// BError Business error implementation
type BError struct {
err Error
data any
}
func (e *BError) Msg() string {
return e.err.Msg()
}
func (e *BError) Code() int {
return e.err.Code()
}
func (e *BError) Error() string {
return e.err.Error()
}
func (e *BError) Data() any {
return e.data
}
type defaultErr struct {
code int
msg string
@ -21,10 +41,54 @@ func (e *defaultErr) Code() int {
return e.code
}
// NewError create a error
func NewError(code int, msg string) Error {
return &defaultErr{code: code, msg: msg}
}
// NewParameterError create a Parameter error
func NewParameterError(msg string, ext ...int) Error {
var code = http.StatusBadRequest
if len(ext) > 0 {
code = ext[0]
}
return NewError(code, msg)
}
// NewBusinessError create a business error
func NewBusinessError(msg string, ext ...any) BusinessError {
var code = 0
var data any = nil
if len(ext) > 0 {
i, ok := ext[0].(int)
if ok {
code = i
}
}
if len(ext) > 1 {
data = ext[1]
}
return &BError{err: NewError(code, msg), data: data}
}
// ToError translate any type to An Error
func ToError(input any) Error {
if input == nil {
return nil
}
switch input.(type) {
case Error:
return input.(Error)
case error:
return NewInnerError(input.(error).Error(), http.StatusInternalServerError)
case string:
return NewInnerError(input.(string), http.StatusInternalServerError)
default:
return NewInnerError(fmt.Sprintf("%v", input), http.StatusInternalServerError)
}
}
type iError struct {
*defaultErr
trace []byte
@ -47,33 +111,37 @@ func NewInnerErrorSkip(msg string, code int, skip int) Error {
return &iError{defaultErr: &defaultErr{code: code, msg: msg}, trace: PanicTrace(2, skip)}
}
// 错误代码gone框架内部错误代码编码空间:1001~1999
// Error Code1001~1999 used for gone framework.
const (
// GonerIdIsExisted GonerId 不存在
// GonerIdIsExisted Goner for the GonerId is existed.
GonerIdIsExisted = 1001 + iota
// CannotFoundGonerById 通过GonerId查找Goner失败
// CannotFoundGonerById cannot find the Goner by the GonerId.
CannotFoundGonerById
// CannotFoundGonerByType 通过类型查找Goner失败
// CannotFoundGonerByType cannot find the Goner by the Type.
CannotFoundGonerByType
//NotCompatible 类型不兼容
//NotCompatible Goner is not compatible with the Type.
NotCompatible
//ReplaceBuryIdParamEmpty 替换性下葬GonerId不能为空
//ReplaceBuryIdParamEmpty Cemetery.ReplaceBury error for the GonerId is empty.
ReplaceBuryIdParamEmpty
//StartError Gone Start flow error.
StartError
//StopError Gone Stop flow error.
StopError
//DbRollForPanic error in rollback of DB transaction for panic.
DbRollForPanic
//MustHaveGonerId error for the GonerId is empty.
MustHaveGonerId
//InjectError error for dependence injection error
InjectError
ConfigError
)
func GonerIdIsExistedError(id GonerId) Error {

View File

@ -1,6 +1,7 @@
package gone
import (
"errors"
"github.com/stretchr/testify/assert"
"strings"
"testing"
@ -12,3 +13,155 @@ func Test_iError_Error(t *testing.T) {
assert.True(t, strings.Contains(s, "Test_iError_Error"))
}
func TestNewBusinessError(t *testing.T) {
type args struct {
msg string
ext []any
}
var data = map[string]any{}
tests := []struct {
name string
args args
want BError
}{
{
name: "single parameter",
args: args{
msg: "error",
ext: []any{},
},
want: BError{
err: NewError(0, "error"),
},
},
{
name: "two parameters",
args: args{
msg: "error",
ext: []any{100},
},
want: BError{
err: NewError(100, "error"),
},
},
{
name: "three parameters",
args: args{
msg: "error",
ext: []any{100, data},
},
want: BError{
err: NewError(100, "error"),
data: data,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want,
*(NewBusinessError(tt.args.msg, tt.args.ext...).(*BError)),
"NewBusinessError(%v, %v)",
tt.args.msg,
tt.args.ext,
)
})
}
businessError := NewBusinessError("error", 100, data)
assert.Equal(t, "error", businessError.Msg())
assert.Equal(t, 100, businessError.Code())
assert.Equal(t, data, businessError.Data())
assert.Equal(t, "GoneError(code=100):error", businessError.Error())
}
func TestNewParameterError(t *testing.T) {
type args struct {
msg string
ext []int
}
tests := []struct {
name string
args args
want defaultErr
}{
{
name: "single parameter",
args: args{
msg: "error",
ext: []int{},
},
want: defaultErr{msg: "error", code: 400},
},
{
name: "single parameter",
args: args{
msg: "error",
ext: []int{401},
},
want: defaultErr{msg: "error", code: 401},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t,
tt.want,
*NewParameterError(tt.args.msg, tt.args.ext...).(*defaultErr),
"NewParameterError(%v, %v)",
tt.args.msg,
tt.args.ext,
)
})
}
}
func TestToError(t *testing.T) {
type args struct {
err error
}
tests := []struct {
name string
args args
want Error
}{
{
name: "err = nil",
args: args{
err: nil,
},
want: nil,
},
{
name: "err is Error",
args: args{
err: NewBusinessError("error", 100),
},
want: NewBusinessError("error", 100),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, ToError(tt.args.err), "ToError(%v)", tt.args.err)
})
}
t.Run("err is not Error", func(t *testing.T) {
err := errors.New("error")
innerError := ToError(err)
assert.Equal(t, 500, innerError.Code())
assert.Equal(t, "error", innerError.Msg())
assert.NotNil(t, innerError.(InnerError).Stack())
})
t.Run("err is string", func(t *testing.T) {
toError := ToError("error")
assert.Equal(t, 500, toError.Code())
assert.Equal(t, "error", toError.Msg())
})
t.Run("err is int", func(t *testing.T) {
toError := ToError(100)
assert.Equal(t, 500, toError.Code())
assert.Equal(t, "100", toError.Msg())
})
}

View File

@ -1,83 +0,0 @@
package gone
import (
"fmt"
"net/http"
)
type BusinessError interface {
Error
Data() any
}
//三种错误:
//内部错误,系统内部错误,只能通过系统升级来修复
//参数错误,输入性错误,错误是由于输入信息导致的问题,需要调整输入
//业务错误,由于内部或外部信息导向的不同业务结果
//func NewInnerError(msg string, code int) Error {
// return gone.NewInnerError(code, msg)
//}
// NewParameterError 新建`参数错误`
func NewParameterError(msg string, ext ...int) Error {
var code = http.StatusBadRequest
if len(ext) > 0 {
code = ext[0]
}
return NewError(code, msg)
}
// NewBusinessError 新建`业务错误`
func NewBusinessError(msg string, ext ...any) BusinessError {
var code = 0
var data any = nil
if len(ext) > 0 {
i, ok := ext[0].(int)
if ok {
code = i
}
}
if len(ext) > 1 {
data = ext[1]
}
return &BError{err: NewError(code, msg), data: data}
}
// ToError 将 golang 提供的 error 转为一个 `gone.Error`
func ToError(input any) Error {
if input == nil {
return nil
}
switch input.(type) {
case Error:
return input.(Error)
case error:
return NewInnerError(input.(error).Error(), http.StatusInternalServerError)
case string:
return NewInnerError(input.(string), http.StatusInternalServerError)
default:
return NewInnerError(fmt.Sprintf("%v", input), http.StatusInternalServerError)
}
}
// BError 业务错误
type BError struct {
err Error
data any
}
func (e *BError) Msg() string {
return e.err.Msg()
}
func (e *BError) Code() int {
return e.err.Code()
}
func (e *BError) Error() string {
return e.err.Error()
}
func (e *BError) Data() any {
return e.data
}

View File

@ -1,159 +0,0 @@
package gone
import (
"errors"
"github.com/stretchr/testify/assert"
"testing"
)
func TestNewBusinessError(t *testing.T) {
type args struct {
msg string
ext []any
}
var data = map[string]any{}
tests := []struct {
name string
args args
want BError
}{
{
name: "single parameter",
args: args{
msg: "error",
ext: []any{},
},
want: BError{
err: NewError(0, "error"),
},
},
{
name: "two parameters",
args: args{
msg: "error",
ext: []any{100},
},
want: BError{
err: NewError(100, "error"),
},
},
{
name: "three parameters",
args: args{
msg: "error",
ext: []any{100, data},
},
want: BError{
err: NewError(100, "error"),
data: data,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want,
*(NewBusinessError(tt.args.msg, tt.args.ext...).(*BError)),
"NewBusinessError(%v, %v)",
tt.args.msg,
tt.args.ext,
)
})
}
businessError := NewBusinessError("error", 100, data)
assert.Equal(t, "error", businessError.Msg())
assert.Equal(t, 100, businessError.Code())
assert.Equal(t, data, businessError.Data())
assert.Equal(t, "GoneError(code=100):error", businessError.Error())
}
func TestNewParameterError(t *testing.T) {
type args struct {
msg string
ext []int
}
tests := []struct {
name string
args args
want defaultErr
}{
{
name: "single parameter",
args: args{
msg: "error",
ext: []int{},
},
want: defaultErr{msg: "error", code: 400},
},
{
name: "single parameter",
args: args{
msg: "error",
ext: []int{401},
},
want: defaultErr{msg: "error", code: 401},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t,
tt.want,
*NewParameterError(tt.args.msg, tt.args.ext...).(*defaultErr),
"NewParameterError(%v, %v)",
tt.args.msg,
tt.args.ext,
)
})
}
}
func TestToError(t *testing.T) {
type args struct {
err error
}
tests := []struct {
name string
args args
want Error
}{
{
name: "err = nil",
args: args{
err: nil,
},
want: nil,
},
{
name: "err is Error",
args: args{
err: NewBusinessError("error", 100),
},
want: NewBusinessError("error", 100),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, ToError(tt.args.err), "ToError(%v)", tt.args.err)
})
}
t.Run("err is not Error", func(t *testing.T) {
err := errors.New("error")
innerError := ToError(err)
assert.Equal(t, 500, innerError.Code())
assert.Equal(t, "error", innerError.Msg())
assert.NotNil(t, innerError.(InnerError).Stack())
})
t.Run("err is string", func(t *testing.T) {
toError := ToError("error")
assert.Equal(t, 500, toError.Code())
assert.Equal(t, "error", toError.Msg())
})
t.Run("err is int", func(t *testing.T) {
toError := ToError(100)
assert.Equal(t, 500, toError.Code())
assert.Equal(t, "100", toError.Msg())
})
}

View File

@ -12,7 +12,6 @@ type ResponseWriter = gin.ResponseWriter
type HandlerFunc any
type IRoutes interface {
// Use 在路由上应用`gin`中间件
Use(...HandlerFunc) IRoutes
Handle(string, string, ...HandlerFunc) IRoutes
@ -27,20 +26,16 @@ type IRoutes interface {
}
type IRouter interface {
// IRoutes 1. 组合了`gone.IRoutes`,可以定义路由
IRoutes
// GetGinRouter 2. 可以获取被封装的ginRouter对象用于操作原始的gin路由
GetGinRouter() gin.IRouter
// Group 3.定义路由分组
Group(string, ...HandlerFunc) RouteGroup
LoadHTMLGlob(pattern string)
}
// RouteGroup 路由分组
// 注入默认的路由分组使用Id: gone-gin-router (`gone.IdGoneGinRouter`)
// RouteGroup route group, which is a wrapper of gin.RouterGroup, and can be injected for mount router.
type RouteGroup interface {
IRouter
}

2
go.mod
View File

@ -14,6 +14,7 @@ require (
github.com/jmoiron/sqlx v1.3.5
github.com/jtolds/gls v4.20.0+incompatible
github.com/magiconair/properties v1.8.7
github.com/mitchellh/mapstructure v1.5.0
github.com/pkg/errors v0.9.1
github.com/robfig/cron/v3 v3.0.1
github.com/sirupsen/logrus v1.9.0
@ -56,7 +57,6 @@ require (
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/leodido/go-urn v1.3.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/onsi/ginkgo/v2 v2.17.2 // indirect

View File

@ -5,9 +5,9 @@
package gin
import (
goneMock "github.com/gone-io/gone"
context "context"
sql "database/sql"
goneMock "github.com/gone-io/gone"
net "net"
reflect "reflect"
time "time"
@ -186,6 +186,20 @@ func (mr *MockTombMockRecorder) GetId() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetId", reflect.TypeOf((*MockTomb)(nil).GetId))
}
// GetOrder mocks base method.
func (m *MockTomb) GetOrder() gone.Order {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetOrder")
ret0, _ := ret[0].(gone.Order)
return ret0
}
// GetOrder indicates an expected call of GetOrder.
func (mr *MockTombMockRecorder) GetOrder() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrder", reflect.TypeOf((*MockTomb)(nil).GetOrder))
}
// GonerIsRevive mocks base method.
func (m *MockTomb) GonerIsRevive(flags ...bool) bool {
m.ctrl.T.Helper()
@ -246,6 +260,20 @@ func (mr *MockTombMockRecorder) SetId(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetId", reflect.TypeOf((*MockTomb)(nil).SetId), arg0)
}
// SetOrder mocks base method.
func (m *MockTomb) SetOrder(order gone.Order) gone.Tomb {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetOrder", order)
ret0, _ := ret[0].(gone.Tomb)
return ret0
}
// SetOrder indicates an expected call of SetOrder.
func (mr *MockTombMockRecorder) SetOrder(order interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOrder", reflect.TypeOf((*MockTomb)(nil).SetOrder), order)
}
// MockCemetery is a mock of Cemetery interface.
type MockCemetery struct {
goneMock.Flag
@ -997,6 +1025,86 @@ func (mr *MockInnerErrorMockRecorder) Stack() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stack", reflect.TypeOf((*MockInnerError)(nil).Stack))
}
// MockBusinessError is a mock of BusinessError interface.
type MockBusinessError struct {
goneMock.Flag
ctrl *gomock.Controller
recorder *MockBusinessErrorMockRecorder
}
// MockBusinessErrorMockRecorder is the mock recorder for MockBusinessError.
type MockBusinessErrorMockRecorder struct {
mock *MockBusinessError
}
// NewMockBusinessError creates a new mock instance.
func NewMockBusinessError(ctrl *gomock.Controller) *MockBusinessError {
mock := &MockBusinessError{ctrl: ctrl}
mock.recorder = &MockBusinessErrorMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBusinessError) EXPECT() *MockBusinessErrorMockRecorder {
return m.recorder
}
// Code mocks base method.
func (m *MockBusinessError) Code() int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Code")
ret0, _ := ret[0].(int)
return ret0
}
// Code indicates an expected call of Code.
func (mr *MockBusinessErrorMockRecorder) Code() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Code", reflect.TypeOf((*MockBusinessError)(nil).Code))
}
// Data mocks base method.
func (m *MockBusinessError) Data() any {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Data")
ret0, _ := ret[0].(any)
return ret0
}
// Data indicates an expected call of Data.
func (mr *MockBusinessErrorMockRecorder) Data() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Data", reflect.TypeOf((*MockBusinessError)(nil).Data))
}
// Error mocks base method.
func (m *MockBusinessError) Error() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Error")
ret0, _ := ret[0].(string)
return ret0
}
// Error indicates an expected call of Error.
func (mr *MockBusinessErrorMockRecorder) Error() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockBusinessError)(nil).Error))
}
// Msg mocks base method.
func (m *MockBusinessError) Msg() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Msg")
ret0, _ := ret[0].(string)
return ret0
}
// Msg indicates an expected call of Msg.
func (mr *MockBusinessErrorMockRecorder) Msg() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Msg", reflect.TypeOf((*MockBusinessError)(nil).Msg))
}
// MockLogger is a mock of Logger interface.
type MockLogger struct {
goneMock.Flag

View File

@ -6,8 +6,8 @@ import (
"reflect"
)
//go:generate sh -c "mockgen -package=gin github.com/gin-gonic/gin ResponseWriter > gin_ResponseWriter_mock_test.go"
//go:generate sh -c "mockgen -package=gin net Listener > net_Listener_mock_test.go"
//go:generate sh -c "mockgen -package=gin github.com/gin-gonic/gin ResponseWriter > gin_response_writer_mock_test.go"
//go:generate sh -c "mockgen -package=gin net Listener > net_listener_mock_test.go"
//go:generate sh -c "mockgen -package=gin -source=../../gin_interface.go |gone mock -o gone_gin_mock_test.go"
//go:generate sh -c "mockgen -package=gin -source=../../interface.go |gone mock -o gone_mock_test.go"
//go:generate sh -c "mockgen -package=gin -self_package=github.com/gone-io/gone/goner/gin -source=interface.go |gone mock -o mock_test.go"

View File

@ -5,9 +5,9 @@
package gone_grpc
import (
goneMock "github.com/gone-io/gone"
context "context"
sql "database/sql"
goneMock "github.com/gone-io/gone"
net "net"
reflect "reflect"
time "time"
@ -186,6 +186,20 @@ func (mr *MockTombMockRecorder) GetId() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetId", reflect.TypeOf((*MockTomb)(nil).GetId))
}
// GetOrder mocks base method.
func (m *MockTomb) GetOrder() gone.Order {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetOrder")
ret0, _ := ret[0].(gone.Order)
return ret0
}
// GetOrder indicates an expected call of GetOrder.
func (mr *MockTombMockRecorder) GetOrder() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrder", reflect.TypeOf((*MockTomb)(nil).GetOrder))
}
// GonerIsRevive mocks base method.
func (m *MockTomb) GonerIsRevive(flags ...bool) bool {
m.ctrl.T.Helper()
@ -246,6 +260,20 @@ func (mr *MockTombMockRecorder) SetId(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetId", reflect.TypeOf((*MockTomb)(nil).SetId), arg0)
}
// SetOrder mocks base method.
func (m *MockTomb) SetOrder(order gone.Order) gone.Tomb {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetOrder", order)
ret0, _ := ret[0].(gone.Tomb)
return ret0
}
// SetOrder indicates an expected call of SetOrder.
func (mr *MockTombMockRecorder) SetOrder(order interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOrder", reflect.TypeOf((*MockTomb)(nil).SetOrder), order)
}
// MockCemetery is a mock of Cemetery interface.
type MockCemetery struct {
goneMock.Flag
@ -997,6 +1025,86 @@ func (mr *MockInnerErrorMockRecorder) Stack() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stack", reflect.TypeOf((*MockInnerError)(nil).Stack))
}
// MockBusinessError is a mock of BusinessError interface.
type MockBusinessError struct {
goneMock.Flag
ctrl *gomock.Controller
recorder *MockBusinessErrorMockRecorder
}
// MockBusinessErrorMockRecorder is the mock recorder for MockBusinessError.
type MockBusinessErrorMockRecorder struct {
mock *MockBusinessError
}
// NewMockBusinessError creates a new mock instance.
func NewMockBusinessError(ctrl *gomock.Controller) *MockBusinessError {
mock := &MockBusinessError{ctrl: ctrl}
mock.recorder = &MockBusinessErrorMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBusinessError) EXPECT() *MockBusinessErrorMockRecorder {
return m.recorder
}
// Code mocks base method.
func (m *MockBusinessError) Code() int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Code")
ret0, _ := ret[0].(int)
return ret0
}
// Code indicates an expected call of Code.
func (mr *MockBusinessErrorMockRecorder) Code() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Code", reflect.TypeOf((*MockBusinessError)(nil).Code))
}
// Data mocks base method.
func (m *MockBusinessError) Data() any {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Data")
ret0, _ := ret[0].(any)
return ret0
}
// Data indicates an expected call of Data.
func (mr *MockBusinessErrorMockRecorder) Data() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Data", reflect.TypeOf((*MockBusinessError)(nil).Data))
}
// Error mocks base method.
func (m *MockBusinessError) Error() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Error")
ret0, _ := ret[0].(string)
return ret0
}
// Error indicates an expected call of Error.
func (mr *MockBusinessErrorMockRecorder) Error() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockBusinessError)(nil).Error))
}
// Msg mocks base method.
func (m *MockBusinessError) Msg() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Msg")
ret0, _ := ret[0].(string)
return ret0
}
// Msg indicates an expected call of Msg.
func (mr *MockBusinessErrorMockRecorder) Msg() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Msg", reflect.TypeOf((*MockBusinessError)(nil).Msg))
}
// MockLogger is a mock of Logger interface.
type MockLogger struct {
goneMock.Flag

View File

@ -2,7 +2,7 @@ package gone_grpc
import "google.golang.org/grpc"
//go:generate sh -c "mockgen -package=gone_grpc net Listener > net_Listener_mock_test.go"
//go:generate sh -c "mockgen -package=gone_grpc net Listener > net_listener_mock_test.go"
//go:generate sh -c "mockgen -package=gone_grpc -source=../../interface.go -mock_names=Server=CmuxServer | gone mock -o gone_mock_test.go"
//go:generate sh -c "mockgen -package=gone_grpc -self_package=github.com/gone-io/gone/goner/grpc -source=interface.go -destination=mock_test.go"

View File

@ -57,7 +57,7 @@ func parseLogLevel(level string) logrus.Level {
var l logrus.Level
err := l.UnmarshalText([]byte(level))
if err != nil {
panic(gone.NewInnerError("cannot parse logger level", gone.ConfigError))
return logrus.InfoLevel
}
return l
}

View File

@ -18,7 +18,7 @@ func Test_parseOutput(t *testing.T) {
func Test_parseLogLevel(t *testing.T) {
defer func() {
err := recover()
assert.Error(t, err.(gone.Error))
assert.Nil(t, err)
}()
parseLogLevel("xxx")
}

View File

@ -8,7 +8,7 @@ import (
"time"
)
// New 新建Heaven; Heaven 代表了一个应用程序;
// New build new Heaven
func New(priests ...Priest) Heaven {
cemetery := newCemetery()
h := heaven{
@ -84,7 +84,6 @@ func (h *heaven) installAngelHook() {
}
func (h *heaven) startFlow() {
// start Handlers 顺序调用:先注册的先调用
for _, before := range h.beforeStartHandlers {
err := before(h.cemetery)
h.panicOnError(err)
@ -104,7 +103,6 @@ func (h *heaven) panicOnError(err error) {
}
func (h *heaven) stopFlow() {
// stop Handlers 逆序调用:先注册的后调用
for i := len(h.beforeStopHandlers) - 1; i >= 0; i-- {
before := h.beforeStopHandlers[i]
err := before(h.cemetery)
@ -141,7 +139,7 @@ func (h *heaven) End() Heaven {
return h
}
// AfterStopSignalWaitSecond 收到停机信号后,退出程序等待的时间
// AfterStopSignalWaitSecond , The variable is used to set the time to wait after the stop signal is received.
var AfterStopSignalWaitSecond = 5
func (h *heaven) Stop() Heaven {
@ -158,19 +156,25 @@ func (h *heaven) Stop() Heaven {
return h
}
// BeforeStart register a process function which will be executed before the start of the system.
func (h *heaven) BeforeStart(p Process) Heaven {
h.beforeStartHandlers = append([]Process{p}, h.beforeStartHandlers...)
return h
}
// AfterStart register a process function which will be executed after the start of the system.
func (h *heaven) AfterStart(p Process) Heaven {
h.afterStartHandlers = append(h.afterStartHandlers, p)
return h
}
// BeforeStop register a process function which will be executed before the stop of the system.
func (h *heaven) BeforeStop(p Process) Heaven {
h.beforeStopHandlers = append([]Process{p}, h.beforeStopHandlers...)
return h
}
// AfterStop register a process function which will be executed after the stop of the system.
func (h *heaven) AfterStop(p Process) Heaven {
h.afterStopHandlers = append(h.afterStopHandlers, p)
return h

View File

@ -9,7 +9,7 @@ import (
"time"
)
// PanicTrace 用于获取调用者的堆栈信息
// PanicTrace used for getting panic stack
func PanicTrace(kb int, skip int) []byte {
stack := make([]byte, kb<<10) //4KB
length := runtime.Stack(stack, true)
@ -38,12 +38,12 @@ func PanicTrace(kb int, skip int) []byte {
return stack
}
// GetFuncName 获取某个函数的名字
// GetFuncName get function name
func GetFuncName(f any) string {
return strings.TrimSuffix(runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(), "-fm")
}
// GetInterfaceType 获取接口的类型
// GetInterfaceType get interface type
func GetInterfaceType[T any](t *T) reflect.Type {
return reflect.TypeOf(t).Elem()
}
@ -79,7 +79,7 @@ func IsCompatible(t reflect.Type, goner any) bool {
}
}
func (c *cemetery) setFieldValue(v reflect.Value, ref any) {
func setFieldValue(v reflect.Value, ref any) {
t := v.Type()
switch t.Kind() {

36
ids.go
View File

@ -1,52 +1,54 @@
package gone
// Gone框架中的内置组件ID
// GonerIds for Gone framework inner Goners
const (
// IdGoneHeaven 天堂组件的ID代码了程序本身Gone程序启动时默认注入
// IdGoneHeaven , The GonerId of Heaven Goner, which represents the program itself, and which is injected by default when it starts.
IdGoneHeaven GonerId = "gone-heaven"
// IdGoneCemetery 坟墓组件的ID是完成依赖注入的关键组件Gone程序启动时默认注入
// IdGoneCemetery , The GonerId of Cemetery Goner, which is Dependence Injection Key Goner, and which is injected by default.
IdGoneCemetery GonerId = "gone-cemetery"
//IdGoneTestKit 测试箱,调用 gone.Test 或者 gone.TestAt 时,会将测试箱注入到程序;非测试代码中不应该注入该组件
// IdGoneTestKit , The GonerId of TestKit Goner, which is injected by default when using gone.Test or gone.TestAt to run test code.
IdGoneTestKit GonerId = "gone-test-kit"
// 配置、日志、Tracer 一起构成Gone框架的基础Goner可以使用 [goner.BasePriest](goner#BasePriest) 牧师函数批量安葬
//IdConfig 配置 Goner 的ID提过能配置能力
//IdConfig , The GonerId of Config Goner, which can be used for Injecting Configs from files or envs.
IdConfig GonerId = "config"
//IdGoneConfigure 配置器 Goner 的ID
//IdGoneConfigure , The GonerId of Configure Goner, which is used to read configs from devices.
IdGoneConfigure GonerId = "gone-configure"
// IdGoneTracer Tracer Goner 的ID提供日志追踪能力
// IdGoneTracer ,The GonerId of Tracer
IdGoneTracer GonerId = "gone-tracer"
// IdGoneLogger 日志 Goner 的ID用于日志打印
// IdGoneLogger , The GonerId of Logger
IdGoneLogger GonerId = "gone-logger"
//IdGoneCMux [cmux Goner](/goner/cmux#Server) ID
// IdGoneCMux , The GonerId of CMuxServer
IdGoneCMux GonerId = "gone-cmux"
//IdGoneGin Gin相关的组件ID可以使用 [goner.GinPriest](goner#GinPriest) 牧师函数批量安葬
// IdGoneGin , IdGoneGinRouter , IdGoneGinProcessor, IdGoneGinProxy, IdGoneGinResponser, IdHttpInjector;
// The GonerIds of Goners in goner/gin, which integrates gin framework for web request.
IdGoneGin GonerId = "gone-gin"
IdGoneGinRouter GonerId = "gone-gin-router"
IdGoneGinProcessor GonerId = "gone-gin-processor"
IdGoneGinProxy GonerId = "gone-gin-proxy"
IdGoneGinResponser GonerId = "gone-gin-responser"
IdHttpInjector GonerId = "http"
IdHttpInjector GonerId = "http"
//IdGoneXorm Xorm Goner 的ID封装了xorm用于操作数据库使用 [goner.XormPriest](goner#XormPriest) 牧师函数安葬
// IdGoneXorm , The GonerId of XormEngine Goner, which is for xorm engine.
IdGoneXorm GonerId = "gone-xorm"
//IdGoneRedisPool redis pool goner; redis 相关 Goner使用 [goner.RedisPriest](goner#RedisPriest) 牧师函数安葬
// IdGoneRedisPool ,IdGoneRedisCache, IdGoneRedisKey, IdGoneRedisLocker, IdGoneRedisProvider
// The GonerIds of Goners in goner/redis, which integrates redis framework for cache and locker.
IdGoneRedisPool GonerId = "gone-redis-pool"
IdGoneRedisCache GonerId = "gone-redis-cache"
IdGoneRedisKey GonerId = "gone-redis-key"
IdGoneRedisLocker GonerId = "gone-redis-locker"
IdGoneRedisProvider GonerId = "gone-redis-provider"
// IdGoneSchedule 定时器Goner使用 [goner.SchedulePriest](goner#SchedulePriest) 牧师函数安葬
// IdGoneSchedule , The GonerId of Schedule Goner, which is for schedule in goner/schedule.
IdGoneSchedule GonerId = "gone-schedule"
// IdGoneReq , The GonerId of urllib.Client Goner, which is for request in goner/urllib.
IdGoneReq GonerId = "gone-urllib"
)

View File

@ -161,6 +161,13 @@ type Vampire2 interface {
Suck(conf string, v reflect.Value, field reflect.StructField) error
}
/*
Three errors:
- Internal error, internal system error, which can only be repaired by system upgrade.
- Parameter error, input error, error is caused by input information, and input needs to be adjusted.
- Business error, due to different business results guided by internal or external information
*/
// Error normal error
type Error interface {
error
@ -168,12 +175,18 @@ type Error interface {
Code() int
}
// InnerError which has stack
// InnerError which has stack, and which is used for Internal error
type InnerError interface {
Error
Stack() []byte
}
// BusinessError which has data, and which is used for Business error
type BusinessError interface {
Error
Data() any
}
// Logger log interface
type Logger interface {
Tracef(format string, args ...any)

View File

@ -180,6 +180,20 @@ func (mr *MockTombMockRecorder) GetId() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetId", reflect.TypeOf((*MockTomb)(nil).GetId))
}
// GetOrder mocks base method.
func (m *MockTomb) GetOrder() Order {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetOrder")
ret0, _ := ret[0].(Order)
return ret0
}
// GetOrder indicates an expected call of GetOrder.
func (mr *MockTombMockRecorder) GetOrder() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOrder", reflect.TypeOf((*MockTomb)(nil).GetOrder))
}
// GonerIsRevive mocks base method.
func (m *MockTomb) GonerIsRevive(flags ...bool) bool {
m.ctrl.T.Helper()
@ -240,6 +254,20 @@ func (mr *MockTombMockRecorder) SetId(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetId", reflect.TypeOf((*MockTomb)(nil).SetId), arg0)
}
// SetOrder mocks base method.
func (m *MockTomb) SetOrder(order Order) Tomb {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetOrder", order)
ret0, _ := ret[0].(Tomb)
return ret0
}
// SetOrder indicates an expected call of SetOrder.
func (mr *MockTombMockRecorder) SetOrder(order interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetOrder", reflect.TypeOf((*MockTomb)(nil).SetOrder), order)
}
// MockCemetery is a mock of Cemetery interface.
type MockCemetery struct {
ctrl *gomock.Controller
@ -982,6 +1010,85 @@ func (mr *MockInnerErrorMockRecorder) Stack() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stack", reflect.TypeOf((*MockInnerError)(nil).Stack))
}
// MockBusinessError is a mock of BusinessError interface.
type MockBusinessError struct {
ctrl *gomock.Controller
recorder *MockBusinessErrorMockRecorder
}
// MockBusinessErrorMockRecorder is the mock recorder for MockBusinessError.
type MockBusinessErrorMockRecorder struct {
mock *MockBusinessError
}
// NewMockBusinessError creates a new mock instance.
func NewMockBusinessError(ctrl *gomock.Controller) *MockBusinessError {
mock := &MockBusinessError{ctrl: ctrl}
mock.recorder = &MockBusinessErrorMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBusinessError) EXPECT() *MockBusinessErrorMockRecorder {
return m.recorder
}
// Code mocks base method.
func (m *MockBusinessError) Code() int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Code")
ret0, _ := ret[0].(int)
return ret0
}
// Code indicates an expected call of Code.
func (mr *MockBusinessErrorMockRecorder) Code() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Code", reflect.TypeOf((*MockBusinessError)(nil).Code))
}
// Data mocks base method.
func (m *MockBusinessError) Data() any {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Data")
ret0, _ := ret[0].(any)
return ret0
}
// Data indicates an expected call of Data.
func (mr *MockBusinessErrorMockRecorder) Data() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Data", reflect.TypeOf((*MockBusinessError)(nil).Data))
}
// Error mocks base method.
func (m *MockBusinessError) Error() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Error")
ret0, _ := ret[0].(string)
return ret0
}
// Error indicates an expected call of Error.
func (mr *MockBusinessErrorMockRecorder) Error() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockBusinessError)(nil).Error))
}
// Msg mocks base method.
func (m *MockBusinessError) Msg() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Msg")
ret0, _ := ret[0].(string)
return ret0
}
// Msg indicates an expected call of Msg.
func (mr *MockBusinessErrorMockRecorder) Msg() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Msg", reflect.TypeOf((*MockBusinessError)(nil).Msg))
}
// MockLogger is a mock of Logger interface.
type MockLogger struct {
ctrl *gomock.Controller

View File

@ -58,14 +58,20 @@ func Prepare(priests ...Priest) *Preparer {
}
}
// Run 开始运行一个Gone程序`gone.Run` 和 `gone.Serve` 的区别是:
// 1. gone.Serve启动的程序主协程会调用 Heaven.WaitEnd 挂起等待停机信号,可以用于服务程序的开发
// 2. gone.Run启动的程序主协程则不会挂起运行完就结束适合开发一致性运行的代码
/*
Run A Gone Program
gone.Run vs gone.Serve:
- gone.Run, The main goroutine never hangs, and the program is terminated when the main goroutine exits.
- gone.Serve, The main goroutine calls Heaven.WaitEnd and hangs, and the program waiting for the stop signal for exiting.
*/
func Run(priests ...Priest) {
Prepare(priests...).Run()
}
// Serve 开始服务,参考[Run](#Run)
// Serve Start for A Gone Server Program.
func Serve(priests ...Priest) {
Prepare(priests...).Serve()
}

23
test.go
View File

@ -52,15 +52,20 @@ func (p *Preparer) testKit() *Preparer {
return p
}
// Test Use for writing test cases
// example:
//
// gone.Prepare(priests...).Test(func(in struct{
// cemetery Cemetery `gone:"*"`
// }) {
//
// // test code
// })
/*
Test Use for writing test cases
example:
```go
gone.Prepare(priests...).Test(func(in struct{
cemetery Cemetery `gone:"*"`
}) {
// test code
})
```
*/
func (p *Preparer) Test(fn any) {
p.testKit().AfterStart(fn).Run()
}