diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..6487997 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/unistack-org/micro-wrapper-recovery/v3 + +go 1.16 + +require github.com/unistack-org/micro/v3 v3.6.2 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..fbc1725 --- /dev/null +++ b/go.sum @@ -0,0 +1,28 @@ +github.com/ef-ds/deque v1.0.4/go.mod h1:gXDnTC3yqvBcHbq2lcExjtAcVrOnJCbMcZXmuj8Z4tg= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/silas/dag v0.0.0-20210121180416-41cf55125c34/go.mod h1:7RTUFBdIRC9nZ7/3RyRNH1bdqIShrDejd1YbLwgPS+I= +github.com/unistack-org/micro-proto v0.0.5 h1:DIC97Hufa2nGjuvTsfToD9laEOKddWMRTzeCfBwJ1j8= +github.com/unistack-org/micro-proto v0.0.5/go.mod h1:EuI7UlfGXmT1hy6WacULib9LbNgRnDYQvTCFoLgKM2I= +github.com/unistack-org/micro/v3 v3.6.2 h1:hr/1GyDA+g9tcsSTFd1sJWZTQz5cBZD+3nD+6gCUjHI= +github.com/unistack-org/micro/v3 v3.6.2/go.mod h1:X8UIH1JK4/jYN/CtvxJ6d+HrfqzmoVQc1no8Homy+ww= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/wrapper.go b/wrapper.go new file mode 100644 index 0000000..a573b32 --- /dev/null +++ b/wrapper.go @@ -0,0 +1,134 @@ +package recovery + +import ( + "context" + "fmt" + + "github.com/unistack-org/micro/v3/server" +) + +type wrapper struct { + serverHandlerFunc func(context.Context, server.Request, interface{}, error) error + serverSubscriberFunc func(context.Context, server.Message, error) error + /* + clientCallFunc func(context.Context, string, client.Request, interface{}, client.CallOptions, error) error + clientClient func(client.Client, error) error + */ +} + +func NewHandlerWrapper(fn func(context.Context, server.Request, interface{}, error) error) server.HandlerWrapper { + handler := &wrapper{ + serverHandlerFunc: fn, + } + return handler.HandlerFunc +} + +func (w *wrapper) HandlerFunc(fn server.HandlerFunc) server.HandlerFunc { + return func(ctx context.Context, req server.Request, rsp interface{}) (err error) { + defer func() { + r := recover() + switch verr := r.(type) { + case nil: + return + case error: + err = w.serverHandlerFunc(ctx, req, rsp, verr) + default: + err = w.serverHandlerFunc(ctx, req, rsp, fmt.Errorf("%v", r)) + } + }() + err = fn(ctx, req, rsp) + return err + } +} + +func NewSubscriberWrapper(fn func(context.Context, server.Message, error) error) server.SubscriberWrapper { + handler := &wrapper{ + serverSubscriberFunc: fn, + } + return handler.SubscriberFunc +} + +func (w *wrapper) SubscriberFunc(fn server.SubscriberFunc) server.SubscriberFunc { + return func(ctx context.Context, msg server.Message) (err error) { + defer func() { + r := recover() + switch verr := r.(type) { + case nil: + return + case error: + err = w.serverSubscriberFunc(ctx, msg, verr) + default: + err = w.serverSubscriberFunc(ctx, msg, fmt.Errorf("%v", r)) + } + }() + err = fn(ctx, msg) + return err + } +} + +/* +func NewClientWrapper() client.Wrapper { + return func(c client.Client) client.Client { + handler := &wrapper{ + clientClient: c, + } + return handler + } +} + +func NewCallWrapper() client.CallWrapper { + return func(fn client.CallFunc) client.CallFunc { + handler := &wrapper{ + clientCallFunc: fn, + } + return handler.CallFunc + } +} + +func (w *wrapper) CallFunc(ctx context.Context, addr string, req client.Request, rsp interface{}, opts client.CallOptions) (err error) { + defer func() { + r := recover() + switch verr := r.(type) { + case nil: + return + case error: + err = w.clientCallFunc(ctx, addr, req, rsp, opts, verr) + default: + err = w.clientCallFunc(ctx, addr, req, rsp, opts, fmt.Errorf("%v", r)) + } + }() + err = w.CallFunc(ctx, addr, req, rsp, opts) + return err +} + +func (w *wrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { + defer func() { + r := recover() + switch verr := r.(type) { + case nil: + return + case error: + err = w.clientClient.Call(ctx, addr, req, rsp, opts, verr) + default: + err = w.clientClient.Call(ctx, addr, req, rsp, opts, fmt.Errorf("%v", r)) + } + }() + err = w.clientClient.Call(ctx, req, rsp, opts...) + return err +} + +func (w *wrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) { + + stream, err := w.Client.Stream(ctx, req, opts...) + + return stream, err +} + +func (w *wrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error { + + err := w.Client.Publish(ctx, p, opts...) + + + return err +} +*/