Skip to content

Commit a32b50f

Browse files
author
Aryan Tikarya
committed
handle pointer and value in get code
1 parent ef506b1 commit a32b50f

File tree

5 files changed

+139
-17
lines changed

5 files changed

+139
-17
lines changed

errors.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import (
66
"reflect"
77
)
88

9-
const eTempWSError = -1111111
9+
const (
10+
eTempWSError = -1111111
11+
defaultErrorCode = 1
12+
)
1013

1114
type RPCConnectionError struct {
1215
err error
@@ -54,12 +57,38 @@ func (e *Errors) Register(c ErrorCode, typ interface{}) {
5457
e.byCode[c] = rt
5558
}
5659

60+
func (e *Errors) getErrorCode(err error) ErrorCode {
61+
var code ErrorCode = defaultErrorCode
62+
63+
// First, try direct type matching
64+
if c, ok := e.byType[reflect.TypeOf(err)]; ok {
65+
return c
66+
}
67+
68+
// Handle pointer vs. value type discrepancies
69+
errType := reflect.TypeOf(err)
70+
if errType.Kind() == reflect.Ptr {
71+
// Try matching the value type
72+
if c, ok := e.byType[errType.Elem()]; ok {
73+
return c
74+
}
75+
} else {
76+
// Try matching the pointer type
77+
ptrType := reflect.PointerTo(errType)
78+
if c, ok := e.byType[ptrType]; ok {
79+
return c
80+
}
81+
}
82+
83+
return code // Return default code if no match found
84+
}
85+
5786
type marshalable interface {
5887
json.Marshaler
5988
json.Unmarshaler
6089
}
6190

62-
type ErrorCodec interface {
91+
type RPCErrorCodec interface {
6392
FromJSONRPCError(JSONRPCError) error
6493
ToJSONRPCError() (JSONRPCError, error)
6594
}

errors_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package jsonrpc
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
// Define a custom error type for testing
11+
type PointerReceiverError struct {
12+
Message string
13+
}
14+
15+
func (e *PointerReceiverError) Error() string {
16+
return e.Message
17+
}
18+
19+
type ValueReceiverError struct {
20+
Message string
21+
}
22+
23+
func (e ValueReceiverError) Error() string {
24+
return e.Message
25+
}
26+
27+
// Another custom error type
28+
type AnotherTestError struct {
29+
Detail string
30+
}
31+
32+
func (e *AnotherTestError) Error() string {
33+
return e.Detail
34+
}
35+
36+
// Non-error type for negative testing
37+
type NotAnError struct {
38+
Field string
39+
}
40+
41+
func TestNewErrors(t *testing.T) {
42+
errs := NewErrors()
43+
44+
if errs.byType == nil {
45+
t.Error("Errors.byType should be initialized")
46+
}
47+
48+
if errs.byCode == nil {
49+
t.Error("Errors.byCode should be initialized")
50+
}
51+
52+
// Check initial registration
53+
expectedType := reflect.TypeOf(&RPCConnectionError{})
54+
if code, exists := errs.byCode[eTempWSError]; !exists {
55+
t.Errorf("Expected initial ErrorCode %d to be registered", eTempWSError)
56+
} else if code != expectedType {
57+
t.Errorf("Expected type %v for ErrorCode %d, got %v", expectedType, eTempWSError, code)
58+
}
59+
}
60+
61+
func TestErrors_GetCode_PointerAndValueTypes(t *testing.T) {
62+
errs := NewErrors()
63+
64+
// Register TestError with ErrorCode 100
65+
errs.Register(100, new(*PointerReceiverError))
66+
errs.Register(101, new(*ValueReceiverError))
67+
68+
// Create both pointer and value instances
69+
ptrErr := &PointerReceiverError{Message: "pointer error"}
70+
valErr := ValueReceiverError{Message: "value error"}
71+
72+
tests := []struct {
73+
name string
74+
inputErr error
75+
wantCode ErrorCode
76+
}{
77+
{
78+
name: "Pointer error",
79+
inputErr: ptrErr,
80+
wantCode: 100,
81+
},
82+
{
83+
name: "Value error (direct, should not match)",
84+
inputErr: valErr,
85+
wantCode: 101,
86+
},
87+
}
88+
89+
for _, tt := range tests {
90+
t.Run(tt.name, func(t *testing.T) {
91+
gotCode := errs.getErrorCode(tt.inputErr)
92+
require.Equal(t, tt.wantCode, gotCode, "error code mismatch for %s", tt.name)
93+
})
94+
}
95+
}

handler.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,21 +270,19 @@ func (s *handler) getSpan(ctx context.Context, req request) (context.Context, *t
270270
}
271271

272272
func (s *handler) createError(err error) *JSONRPCError {
273-
var code ErrorCode = 1
274-
if s.errors != nil {
275-
c, ok := s.errors.byType[reflect.TypeOf(err)]
276-
if ok {
277-
code = c
278-
}
273+
if err == nil {
274+
return nil
279275
}
280276

277+
code := s.errors.getErrorCode(err)
278+
281279
out := &JSONRPCError{
282280
Code: code,
283281
Message: err.Error(),
284282
}
285283

286284
switch m := err.(type) {
287-
case ErrorCodec:
285+
case RPCErrorCodec:
288286
o, err := m.ToJSONRPCError()
289287
if err != nil {
290288
log.Warnf("Failed to convert error to JSONRPCError: %v", err)
@@ -455,12 +453,12 @@ func (s *handler) handle(ctx context.Context, req request, w func(func(io.Writer
455453
Message: err.Error(),
456454
}
457455

458-
if m, ok := err.(ErrorCodec); ok {
459-
respErr, err := m.ToJSONRPCError()
456+
if m, ok := err.(RPCErrorCodec); ok {
457+
rpcErr, err := m.ToJSONRPCError()
460458
if err != nil {
461459
log.Warnf("Failed to convert error to JSONRPCError: %v", err)
462460
} else {
463-
resp.Error.Data = respErr.Data
461+
respErr.Data = rpcErr.Data
464462
}
465463
}
466464

resp_error_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func (e *SimpleError) ToJSONRPCError() (JSONRPCError, error) {
3535
return JSONRPCError{Message: e.Message}, nil
3636
}
3737

38-
var _ ErrorCodec = (*SimpleError)(nil)
38+
var _ RPCErrorCodec = (*SimpleError)(nil)
3939

4040
type DataStringError struct {
4141
Message string `json:"message"`
@@ -62,7 +62,7 @@ func (e *DataStringError) ToJSONRPCError() (JSONRPCError, error) {
6262
return JSONRPCError{Message: e.Message, Data: e.Data}, nil
6363
}
6464

65-
var _ ErrorCodec = (*DataStringError)(nil)
65+
var _ RPCErrorCodec = (*DataStringError)(nil)
6666

6767
type DataComplexError struct {
6868
Message string
@@ -94,7 +94,7 @@ func (e *DataComplexError) ToJSONRPCError() (JSONRPCError, error) {
9494
return JSONRPCError{Message: e.Message, Data: data}, nil
9595
}
9696

97-
var _ ErrorCodec = (*DataComplexError)(nil)
97+
var _ RPCErrorCodec = (*DataComplexError)(nil)
9898

9999
type MetaError struct {
100100
Message string

response.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (e *JSONRPCError) Error() string {
5252
var (
5353
_ error = (*JSONRPCError)(nil)
5454
marshalableRT = reflect.TypeOf(new(marshalable)).Elem()
55-
unmarshalableRT = reflect.TypeOf(new(ErrorCodec)).Elem()
55+
unmarshalableRT = reflect.TypeOf(new(RPCErrorCodec)).Elem()
5656
)
5757

5858
func (e *JSONRPCError) val(errors *Errors) reflect.Value {
@@ -67,7 +67,7 @@ func (e *JSONRPCError) val(errors *Errors) reflect.Value {
6767
}
6868

6969
if v.Type().Implements(unmarshalableRT) {
70-
_ = v.Interface().(ErrorCodec).FromJSONRPCError(*e)
70+
_ = v.Interface().(RPCErrorCodec).FromJSONRPCError(*e)
7171
}
7272

7373
if len(e.Meta) > 0 && v.Type().Implements(marshalableRT) {

0 commit comments

Comments
 (0)