mirror of
https://github.com/foomo/gotsrpc.git
synced 2025-10-16 12:35:35 +00:00
fix: add client error unwrap
This commit is contained in:
parent
f8e193bcd6
commit
07c3475cc9
@ -9,3 +9,11 @@ func NewClientError(err error) *ClientError {
|
|||||||
error: err,
|
error: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap interface
|
||||||
|
func (e *ClientError) Unwrap() error {
|
||||||
|
if e != nil && e.error != nil {
|
||||||
|
return e.error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -16,6 +16,9 @@ export class ServiceClient {
|
|||||||
async boolSlice(v:Array<boolean>|null):Promise<Array<boolean>|null> {
|
async boolSlice(v:Array<boolean>|null):Promise<Array<boolean>|null> {
|
||||||
return (await this.transport<{0:Array<boolean>|null}>("BoolSlice", [v]))[0]
|
return (await this.transport<{0:Array<boolean>|null}>("BoolSlice", [v]))[0]
|
||||||
}
|
}
|
||||||
|
async context():Promise<void> {
|
||||||
|
await this.transport<void>("Context", [])
|
||||||
|
}
|
||||||
async empty():Promise<void> {
|
async empty():Promise<void> {
|
||||||
await this.transport<void>("Empty", [])
|
await this.transport<void>("Empty", [])
|
||||||
}
|
}
|
||||||
|
|||||||
27
example/basic/main_test.go
Normal file
27
example/basic/main_test.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package main_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/foomo/gotsrpc/v2/example/basic/service"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestContextCanceled(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.TODO())
|
||||||
|
go func() {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
cancel()
|
||||||
|
}()
|
||||||
|
|
||||||
|
svr := httptest.NewServer(service.NewDefaultServiceGoTSRPCProxy(&service.Handler{}))
|
||||||
|
defer svr.Close()
|
||||||
|
|
||||||
|
client := service.NewDefaultServiceGoTSRPCClient(svr.URL)
|
||||||
|
|
||||||
|
clientErr := client.Context(ctx)
|
||||||
|
assert.ErrorIs(t, clientErr, context.Canceled)
|
||||||
|
}
|
||||||
@ -42,6 +42,11 @@ type (
|
|||||||
RetBoolSlice_0 []bool
|
RetBoolSlice_0 []bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServiceContextRequest struct {
|
||||||
|
}
|
||||||
|
ServiceContextResponse struct {
|
||||||
|
}
|
||||||
|
|
||||||
ServiceEmptyRequest struct {
|
ServiceEmptyRequest struct {
|
||||||
}
|
}
|
||||||
ServiceEmptyResponse struct {
|
ServiceEmptyResponse struct {
|
||||||
@ -461,6 +466,8 @@ func init() {
|
|||||||
gob.Register(ServiceBoolPtrResponse{})
|
gob.Register(ServiceBoolPtrResponse{})
|
||||||
gob.Register(ServiceBoolSliceRequest{})
|
gob.Register(ServiceBoolSliceRequest{})
|
||||||
gob.Register(ServiceBoolSliceResponse{})
|
gob.Register(ServiceBoolSliceResponse{})
|
||||||
|
gob.Register(ServiceContextRequest{})
|
||||||
|
gob.Register(ServiceContextResponse{})
|
||||||
gob.Register(ServiceEmptyRequest{})
|
gob.Register(ServiceEmptyRequest{})
|
||||||
gob.Register(ServiceEmptyResponse{})
|
gob.Register(ServiceEmptyResponse{})
|
||||||
gob.Register(ServiceFloat32Request{})
|
gob.Register(ServiceFloat32Request{})
|
||||||
@ -631,6 +638,9 @@ func (p *ServiceGoRPCProxy) handler(clientAddr string, request interface{}) (res
|
|||||||
req := request.(ServiceBoolSliceRequest)
|
req := request.(ServiceBoolSliceRequest)
|
||||||
retBoolSlice_0 := p.service.BoolSlice(req.V)
|
retBoolSlice_0 := p.service.BoolSlice(req.V)
|
||||||
response = ServiceBoolSliceResponse{RetBoolSlice_0: retBoolSlice_0}
|
response = ServiceBoolSliceResponse{RetBoolSlice_0: retBoolSlice_0}
|
||||||
|
case "ServiceContextRequest":
|
||||||
|
p.service.Context(nil, nil)
|
||||||
|
response = ServiceContextResponse{}
|
||||||
case "ServiceEmptyRequest":
|
case "ServiceEmptyRequest":
|
||||||
p.service.Empty()
|
p.service.Empty()
|
||||||
response = ServiceEmptyResponse{}
|
response = ServiceEmptyResponse{}
|
||||||
|
|||||||
@ -63,6 +63,16 @@ func (tsc *ServiceGoRPCClient) BoolSlice(v []bool) (retBoolSlice_0 []bool, clien
|
|||||||
return response.RetBoolSlice_0, nil
|
return response.RetBoolSlice_0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tsc *ServiceGoRPCClient) Context() (clientErr error) {
|
||||||
|
req := ServiceContextRequest{}
|
||||||
|
_, rpcCallErr := tsc.Client.Call(req)
|
||||||
|
if rpcCallErr != nil {
|
||||||
|
clientErr = rpcCallErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tsc *ServiceGoRPCClient) Empty() (clientErr error) {
|
func (tsc *ServiceGoRPCClient) Empty() (clientErr error) {
|
||||||
req := ServiceEmptyRequest{}
|
req := ServiceEmptyRequest{}
|
||||||
_, rpcCallErr := tsc.Client.Call(req)
|
_, rpcCallErr := tsc.Client.Call(req)
|
||||||
|
|||||||
@ -14,6 +14,7 @@ const (
|
|||||||
ServiceGoTSRPCProxyBool = "Bool"
|
ServiceGoTSRPCProxyBool = "Bool"
|
||||||
ServiceGoTSRPCProxyBoolPtr = "BoolPtr"
|
ServiceGoTSRPCProxyBoolPtr = "BoolPtr"
|
||||||
ServiceGoTSRPCProxyBoolSlice = "BoolSlice"
|
ServiceGoTSRPCProxyBoolSlice = "BoolSlice"
|
||||||
|
ServiceGoTSRPCProxyContext = "Context"
|
||||||
ServiceGoTSRPCProxyEmpty = "Empty"
|
ServiceGoTSRPCProxyEmpty = "Empty"
|
||||||
ServiceGoTSRPCProxyFloat32 = "Float32"
|
ServiceGoTSRPCProxyFloat32 = "Float32"
|
||||||
ServiceGoTSRPCProxyFloat32Map = "Float32Map"
|
ServiceGoTSRPCProxyFloat32Map = "Float32Map"
|
||||||
@ -176,6 +177,24 @@ func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
gotsrpc.Monitor(w, r, args, rets, callStats)
|
gotsrpc.Monitor(w, r, args, rets, callStats)
|
||||||
return
|
return
|
||||||
|
case ServiceGoTSRPCProxyContext:
|
||||||
|
var (
|
||||||
|
args []interface{}
|
||||||
|
rets []interface{}
|
||||||
|
)
|
||||||
|
executionStart := time.Now()
|
||||||
|
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
|
||||||
|
p.service.Context(&rw, r)
|
||||||
|
callStats.Execution = time.Since(executionStart)
|
||||||
|
if rw.Status() == http.StatusOK {
|
||||||
|
rets = []interface{}{}
|
||||||
|
if err := gotsrpc.Reply(rets, callStats, r, w); err != nil {
|
||||||
|
gotsrpc.ErrorCouldNotReply(w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gotsrpc.Monitor(w, r, args, rets, callStats)
|
||||||
|
return
|
||||||
case ServiceGoTSRPCProxyEmpty:
|
case ServiceGoTSRPCProxyEmpty:
|
||||||
var (
|
var (
|
||||||
args []interface{}
|
args []interface{}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ type ServiceGoTSRPCClient interface {
|
|||||||
Bool(ctx go_context.Context, v bool) (retBool_0 bool, clientErr error)
|
Bool(ctx go_context.Context, v bool) (retBool_0 bool, clientErr error)
|
||||||
BoolPtr(ctx go_context.Context, v bool) (retBoolPtr_0 *bool, clientErr error)
|
BoolPtr(ctx go_context.Context, v bool) (retBoolPtr_0 *bool, clientErr error)
|
||||||
BoolSlice(ctx go_context.Context, v []bool) (retBoolSlice_0 []bool, clientErr error)
|
BoolSlice(ctx go_context.Context, v []bool) (retBoolSlice_0 []bool, clientErr error)
|
||||||
|
Context(ctx go_context.Context) (clientErr error)
|
||||||
Empty(ctx go_context.Context) (clientErr error)
|
Empty(ctx go_context.Context) (clientErr error)
|
||||||
Float32(ctx go_context.Context, v float32) (retFloat32_0 float32, clientErr error)
|
Float32(ctx go_context.Context, v float32) (retFloat32_0 float32, clientErr error)
|
||||||
Float32Map(ctx go_context.Context, v map[float32]interface{}) (retFloat32Map_0 map[float32]interface{}, clientErr error)
|
Float32Map(ctx go_context.Context, v map[float32]interface{}) (retFloat32Map_0 map[float32]interface{}, clientErr error)
|
||||||
@ -126,6 +127,16 @@ func (tsc *HTTPServiceGoTSRPCClient) BoolSlice(ctx go_context.Context, v []bool)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tsc *HTTPServiceGoTSRPCClient) Context(ctx go_context.Context) (clientErr error) {
|
||||||
|
args := []interface{}{}
|
||||||
|
reply := []interface{}{}
|
||||||
|
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "Context", args, reply)
|
||||||
|
if clientErr != nil {
|
||||||
|
clientErr = pkg_errors.WithMessage(clientErr, "failed to call service.ServiceGoTSRPCProxy Context")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (tsc *HTTPServiceGoTSRPCClient) Empty(ctx go_context.Context) (clientErr error) {
|
func (tsc *HTTPServiceGoTSRPCClient) Empty(ctx go_context.Context) (clientErr error) {
|
||||||
args := []interface{}{}
|
args := []interface{}{}
|
||||||
reply := []interface{}{}
|
reply := []interface{}{}
|
||||||
|
|||||||
@ -1,10 +1,20 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type Handler struct{}
|
type Handler struct{}
|
||||||
|
|
||||||
func (h *Handler) Empty() {
|
func (h *Handler) Context(w http.ResponseWriter, r *http.Request) {
|
||||||
|
for r.Context().Err() == nil {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) Empty() {}
|
||||||
|
|
||||||
func (h *Handler) Bool(v bool) bool {
|
func (h *Handler) Bool(v bool) bool {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
|
Context(w http.ResponseWriter, r *http.Request)
|
||||||
Empty()
|
Empty()
|
||||||
Bool(v bool) bool
|
Bool(v bool) bool
|
||||||
BoolPtr(v bool) *bool
|
BoolPtr(v bool) *bool
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
package frontend
|
package frontend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/foomo/gotsrpc/v2/example/errors/service/backend"
|
"github.com/foomo/gotsrpc/v2/example/errors/service/backend"
|
||||||
"github.com/foomo/gotsrpc/v2/example/errors/service/frontend"
|
"github.com/foomo/gotsrpc/v2/example/errors/service/frontend"
|
||||||
@ -18,6 +20,12 @@ func New(client backend.ServiceGoTSRPCClient) *Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) Simple(w http.ResponseWriter, r *http.Request) (e *frontend.ErrSimple) {
|
func (h *Handler) Simple(w http.ResponseWriter, r *http.Request) (e *frontend.ErrSimple) {
|
||||||
|
fmt.Println("==========> incoming")
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
if r.Context().Err() != nil {
|
||||||
|
fmt.Println("==========>" + r.Context().Err().Error())
|
||||||
|
}
|
||||||
|
fmt.Println("<========== outgoing")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os/exec"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -40,7 +39,7 @@ func main() {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
_ = exec.Command("open", "http://127.0.0.1:3000").Run()
|
// _ = exec.Command("open", "http://127.0.0.1:3000").Run()
|
||||||
call()
|
call()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -49,12 +48,30 @@ func main() {
|
|||||||
|
|
||||||
func call() {
|
func call() {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
ctx2, cancel := context.WithCancel(ctx)
|
||||||
|
req, _ := http.NewRequestWithContext(ctx2, "POST", "http://127.0.0.1:3000/service/frontend/Simple", nil)
|
||||||
|
go func() {
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
fmt.Println("cancel")
|
||||||
|
cancel()
|
||||||
|
}()
|
||||||
|
fmt.Println("sending request")
|
||||||
|
res, err := http.DefaultClient.Do(req)
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
fmt.Printf("%v\n", err)
|
||||||
|
fmt.Printf("%v\n", res.StatusCode)
|
||||||
|
|
||||||
c := backendsvs.NewDefaultServiceGoTSRPCClient("http://localhost:3000")
|
c := backendsvs.NewDefaultServiceGoTSRPCClient("http://localhost:3000")
|
||||||
|
|
||||||
{
|
{
|
||||||
fmt.Println("--- Error ----------------------")
|
fmt.Println("--- Error ----------------------")
|
||||||
var gotsrpcErr *gotsrpc.Error
|
var gotsrpcErr *gotsrpc.Error
|
||||||
serviceErr, err := c.Error(ctx)
|
|
||||||
|
ctx2, cancel2 := context.WithCancel(ctx)
|
||||||
|
cancel2()
|
||||||
|
serviceErr, err := c.Error(ctx2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("client error should be nil")
|
panic("client error should be nil")
|
||||||
} else if serviceErr == nil {
|
} else if serviceErr == nil {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user