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,
|
||||
}
|
||||
}
|
||||
|
||||
// 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> {
|
||||
return (await this.transport<{0:Array<boolean>|null}>("BoolSlice", [v]))[0]
|
||||
}
|
||||
async context():Promise<void> {
|
||||
await this.transport<void>("Context", [])
|
||||
}
|
||||
async empty():Promise<void> {
|
||||
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
|
||||
}
|
||||
|
||||
ServiceContextRequest struct {
|
||||
}
|
||||
ServiceContextResponse struct {
|
||||
}
|
||||
|
||||
ServiceEmptyRequest struct {
|
||||
}
|
||||
ServiceEmptyResponse struct {
|
||||
@ -461,6 +466,8 @@ func init() {
|
||||
gob.Register(ServiceBoolPtrResponse{})
|
||||
gob.Register(ServiceBoolSliceRequest{})
|
||||
gob.Register(ServiceBoolSliceResponse{})
|
||||
gob.Register(ServiceContextRequest{})
|
||||
gob.Register(ServiceContextResponse{})
|
||||
gob.Register(ServiceEmptyRequest{})
|
||||
gob.Register(ServiceEmptyResponse{})
|
||||
gob.Register(ServiceFloat32Request{})
|
||||
@ -631,6 +638,9 @@ func (p *ServiceGoRPCProxy) handler(clientAddr string, request interface{}) (res
|
||||
req := request.(ServiceBoolSliceRequest)
|
||||
retBoolSlice_0 := p.service.BoolSlice(req.V)
|
||||
response = ServiceBoolSliceResponse{RetBoolSlice_0: retBoolSlice_0}
|
||||
case "ServiceContextRequest":
|
||||
p.service.Context(nil, nil)
|
||||
response = ServiceContextResponse{}
|
||||
case "ServiceEmptyRequest":
|
||||
p.service.Empty()
|
||||
response = ServiceEmptyResponse{}
|
||||
|
||||
@ -63,6 +63,16 @@ func (tsc *ServiceGoRPCClient) BoolSlice(v []bool) (retBoolSlice_0 []bool, clien
|
||||
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) {
|
||||
req := ServiceEmptyRequest{}
|
||||
_, rpcCallErr := tsc.Client.Call(req)
|
||||
|
||||
@ -14,6 +14,7 @@ const (
|
||||
ServiceGoTSRPCProxyBool = "Bool"
|
||||
ServiceGoTSRPCProxyBoolPtr = "BoolPtr"
|
||||
ServiceGoTSRPCProxyBoolSlice = "BoolSlice"
|
||||
ServiceGoTSRPCProxyContext = "Context"
|
||||
ServiceGoTSRPCProxyEmpty = "Empty"
|
||||
ServiceGoTSRPCProxyFloat32 = "Float32"
|
||||
ServiceGoTSRPCProxyFloat32Map = "Float32Map"
|
||||
@ -176,6 +177,24 @@ func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
gotsrpc.Monitor(w, r, args, rets, callStats)
|
||||
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:
|
||||
var (
|
||||
args []interface{}
|
||||
|
||||
@ -14,6 +14,7 @@ type ServiceGoTSRPCClient interface {
|
||||
Bool(ctx go_context.Context, v bool) (retBool_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)
|
||||
Context(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)
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
args := []interface{}{}
|
||||
reply := []interface{}{}
|
||||
|
||||
@ -1,10 +1,20 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
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 {
|
||||
return v
|
||||
}
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
Context(w http.ResponseWriter, r *http.Request)
|
||||
Empty()
|
||||
Bool(v bool) bool
|
||||
BoolPtr(v bool) *bool
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
package frontend
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/foomo/gotsrpc/v2/example/errors/service/backend"
|
||||
"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) {
|
||||
fmt.Println("==========> incoming")
|
||||
time.Sleep(time.Second)
|
||||
if r.Context().Err() != nil {
|
||||
fmt.Println("==========>" + r.Context().Err().Error())
|
||||
}
|
||||
fmt.Println("<========== outgoing")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -40,7 +39,7 @@ func main() {
|
||||
|
||||
go func() {
|
||||
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()
|
||||
}()
|
||||
|
||||
@ -49,12 +48,30 @@ func main() {
|
||||
|
||||
func call() {
|
||||
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")
|
||||
|
||||
{
|
||||
fmt.Println("--- Error ----------------------")
|
||||
var gotsrpcErr *gotsrpc.Error
|
||||
serviceErr, err := c.Error(ctx)
|
||||
|
||||
ctx2, cancel2 := context.WithCancel(ctx)
|
||||
cancel2()
|
||||
serviceErr, err := c.Error(ctx2)
|
||||
if err != nil {
|
||||
panic("client error should be nil")
|
||||
} else if serviceErr == nil {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user