fix: remove unsafe pointer

This commit is contained in:
Kevin Franklin Kim 2022-07-18 16:08:20 +02:00
parent 16baabced1
commit 195d85e505
6 changed files with 75 additions and 13 deletions

View File

@ -75,6 +75,13 @@ func (h *Handler) MultiScalar(w http.ResponseWriter, r *http.Request) (e *backen
}
}
func (h *Handler) Struct(w http.ResponseWriter, r *http.Request) (e *backend.Struct) {
return &backend.Struct{
Message: "my custom scalar",
Data: "hello world",
}
}
func (h *Handler) TypedError(w http.ResponseWriter, r *http.Request) (e error) {
return ErrTyped
}

View File

@ -1,5 +1,9 @@
package main
// func () error
// func () error => func () *Error => decode => func() error
import (
"context"
"fmt"
@ -89,6 +93,18 @@ func call() {
}
}
{
fmt.Println("-------------------------")
strct, err := c.Struct(ctx)
if err != nil {
panic("client error should be nil")
} else if strct == nil {
panic("service error should not be nil")
} else if strct != nil {
fmt.Println("OK")
}
}
{
fmt.Println("-------------------------")
var gotsrpcErr *gotsrpc.Error

View File

@ -17,6 +17,7 @@ const (
ServiceGoTSRPCProxyMultiScalar = "MultiScalar"
ServiceGoTSRPCProxyScalar = "Scalar"
ServiceGoTSRPCProxyScalarError = "ScalarError"
ServiceGoTSRPCProxyStruct = "Struct"
ServiceGoTSRPCProxyTypedCustomError = "TypedCustomError"
ServiceGoTSRPCProxyTypedError = "TypedError"
ServiceGoTSRPCProxyTypedScalarError = "TypedScalarError"
@ -146,6 +147,24 @@ func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
}
gotsrpc.Monitor(w, r, args, rets, callStats)
return
case ServiceGoTSRPCProxyStruct:
var (
args []interface{}
rets []interface{}
)
executionStart := time.Now()
rw := gotsrpc.ResponseWriter{ResponseWriter: w}
structE := p.service.Struct(&rw, r)
callStats.Execution = time.Since(executionStart)
if rw.Status() == http.StatusOK {
rets = []interface{}{structE}
if err := gotsrpc.Reply(rets, callStats, r, w); err != nil {
gotsrpc.ErrorCouldNotReply(w)
return
}
}
gotsrpc.Monitor(w, r, args, rets, callStats)
return
case ServiceGoTSRPCProxyTypedCustomError:
var (
args []interface{}

View File

@ -16,6 +16,7 @@ type ServiceGoTSRPCClient interface {
MultiScalar(ctx go_context.Context) (e *MultiScalar, clientErr error)
Scalar(ctx go_context.Context) (e *Scalar, clientErr error)
ScalarError(ctx go_context.Context) (e error, clientErr error)
Struct(ctx go_context.Context) (e *Struct, clientErr error)
TypedCustomError(ctx go_context.Context) (e error, clientErr error)
TypedError(ctx go_context.Context) (e error, clientErr error)
TypedScalarError(ctx go_context.Context) (e error, clientErr error)
@ -94,6 +95,16 @@ func (tsc *HTTPServiceGoTSRPCClient) ScalarError(ctx go_context.Context) (e erro
return
}
func (tsc *HTTPServiceGoTSRPCClient) Struct(ctx go_context.Context) (e *Struct, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}
clientErr = tsc.Client.Call(ctx, tsc.URL, tsc.EndPoint, "Struct", args, reply)
if clientErr != nil {
clientErr = pkg_errors.WithMessage(clientErr, "failed to call backend.ServiceGoTSRPCProxy Struct")
}
return
}
func (tsc *HTTPServiceGoTSRPCClient) TypedCustomError(ctx go_context.Context) (e error, clientErr error) {
args := []interface{}{}
reply := []interface{}{&e}

View File

@ -12,6 +12,23 @@ const (
type Scalar string
func (s Scalar) String() string {
return string(s)
}
func (s *Scalar) Error() string {
return s.String()
}
type Struct struct {
Message string `json:"message"`
Data string `json:"data"`
}
func (s *Struct) Error() string {
return s.Message
}
type (
ScalarA string
ScalarB string
@ -36,6 +53,7 @@ type Service interface {
Error(w http.ResponseWriter, r *http.Request) (e error)
Scalar(w http.ResponseWriter, r *http.Request) (e *Scalar)
MultiScalar(w http.ResponseWriter, r *http.Request) (e *MultiScalar)
Struct(w http.ResponseWriter, r *http.Request) (e *Struct)
TypedError(w http.ResponseWriter, r *http.Request) (e error)
ScalarError(w http.ResponseWriter, r *http.Request) (e error)
CustomError(w http.ResponseWriter, r *http.Request) (e error)

View File

@ -4,8 +4,9 @@ import (
"net/http"
"reflect"
"time"
"unsafe"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"github.com/ugorji/go/codec"
)
@ -53,22 +54,12 @@ var msgpackClientHandle = &clientHandle{
return ret, nil
},
afterDecodeReply: func(reply *[]interface{}, wrappedReply []interface{}) error {
ptr := func(v reflect.Value) reflect.Value {
pt := reflect.PtrTo(v.Type()) // create a *T type.
pv := reflect.New(pt.Elem()) // create a reflect.Value of type *T.
pv.Elem().Set(v) // sets pv to point to underlying value of v.
return pv
}
for k, v := range wrappedReply {
if e, ok := v.(*Error); ok && e != nil {
if y, ok := (*reply)[k].(*error); ok {
*y = e
} else {
rv := reflect.ValueOf((*reply)[k]).Elem()
elem := reflect.NewAt(rv.Type().Elem(), unsafe.Pointer(rv.UnsafeAddr())).Elem()
elem.Set(reflect.ValueOf(e.Data).Convert(elem.Type()))
rv.Set(ptr(elem))
} else if err := mapstructure.Decode(e.Data, (*reply)[k]); err != nil {
return errors.Wrap(err, "failed to decode wrapped error")
}
}
}