55 "context"
66 "encoding/base64"
77 "encoding/json"
8- "errors"
98 "fmt"
109 "io"
1110 "reflect"
@@ -66,95 +65,6 @@ type request struct {
6665// Configured by WithMaxRequestSize.
6766const DEFAULT_MAX_REQUEST_SIZE = 100 << 20 // 100 MiB
6867
69- type respError struct {
70- Code ErrorCode `json:"code"`
71- Message string `json:"message"`
72- Meta json.RawMessage `json:"meta,omitempty"`
73- Data interface {} `json:"data,omitempty"`
74- }
75-
76- func (e * respError ) Error () string {
77- if e .Code >= - 32768 && e .Code <= - 32000 {
78- return fmt .Sprintf ("RPC error (%d): %s" , e .Code , e .Message )
79- }
80- return e .Message
81- }
82-
83- func (e * respError ) ErrorData () interface {} {
84- return e .Data
85- }
86-
87- var (
88- marshalableRT = reflect .TypeOf (new (marshalable )).Elem ()
89- errorsRT = reflect .TypeOf (new (ErrorWithData )).Elem ()
90- )
91-
92- func (e * respError ) val (errors * Errors ) reflect.Value {
93- if errors != nil {
94- t , ok := errors .byCode [e .Code ]
95- if ok {
96- var v reflect.Value
97- if t .Kind () == reflect .Ptr {
98- v = reflect .New (t .Elem ())
99- } else {
100- v = reflect .New (t )
101- }
102-
103- if len (e .Meta ) > 0 && v .Type ().Implements (marshalableRT ) {
104- _ = v .Interface ().(marshalable ).UnmarshalJSON (e .Meta )
105- }
106-
107- msgField := v .Elem ().FieldByName ("Message" )
108- if msgField .IsValid () && msgField .CanSet () && msgField .Kind () == reflect .String {
109- msgField .SetString (e .Message )
110- }
111-
112- if v .Type ().Implements (errorsRT ) {
113- dataField := v .Elem ().FieldByName ("Data" )
114- if dataField .IsValid () && dataField .CanSet () {
115- dataField .Set (reflect .ValueOf (e .Data ))
116- }
117- }
118-
119- if t .Kind () != reflect .Ptr {
120- v = v .Elem ()
121- }
122- return v
123- }
124- }
125-
126- return reflect .ValueOf (e )
127- }
128-
129- type response struct {
130- Jsonrpc string `json:"jsonrpc"`
131- Result interface {} `json:"result,omitempty"`
132- ID interface {} `json:"id"`
133- Error * respError `json:"error,omitempty"`
134- }
135-
136- func (r response ) MarshalJSON () ([]byte , error ) {
137- // Custom marshal logic as per JSON-RPC 2.0 spec:
138- // > `result`:
139- // > This member is REQUIRED on success.
140- // > This member MUST NOT exist if there was an error invoking the method.
141- //
142- // > `error`:
143- // > This member is REQUIRED on error.
144- // > This member MUST NOT exist if there was no error triggered during invocation.
145- data := map [string ]interface {}{
146- "jsonrpc" : r .Jsonrpc ,
147- "id" : r .ID ,
148- }
149-
150- if r .Error != nil {
151- data ["error" ] = r .Error
152- } else {
153- data ["result" ] = r .Result
154- }
155- return json .Marshal (data )
156- }
157-
15868type handler struct {
15969 methods map [string ]methodHandler
16070 errors * Errors
@@ -359,7 +269,7 @@ func (s *handler) getSpan(ctx context.Context, req request) (context.Context, *t
359269 return ctx , span
360270}
361271
362- func (s * handler ) createError (err error ) * respError {
272+ func (s * handler ) createError (err error ) * JSONRPCError {
363273 var code ErrorCode = 1
364274 if s .errors != nil {
365275 c , ok := s .errors .byType [reflect .TypeOf (err )]
@@ -368,12 +278,20 @@ func (s *handler) createError(err error) *respError {
368278 }
369279 }
370280
371- out := & respError {
281+ out := & JSONRPCError {
372282 Code : code ,
373283 Message : err .Error (),
374284 }
375285
376- if m , ok := err .(marshalable ); ok {
286+ switch m := err .(type ) {
287+ case ErrorCodec :
288+ o , err := m .ToJSONRPCError ()
289+ if err != nil {
290+ log .Warnf ("Failed to convert error to JSONRPCError: %v" , err )
291+ } else {
292+ out = & o
293+ }
294+ case marshalable :
377295 meta , marshalErr := m .MarshalJSON ()
378296 if marshalErr == nil {
379297 out .Meta = meta
@@ -382,11 +300,6 @@ func (s *handler) createError(err error) *respError {
382300 }
383301 }
384302
385- var ed ErrorWithData
386- if errors .As (err , & ed ) {
387- out .Data = ed .ErrorData ()
388- }
389-
390303 return out
391304}
392305
@@ -536,14 +449,19 @@ func (s *handler) handle(ctx context.Context, req request, w func(func(io.Writer
536449
537450 log .Warnf ("failed to setup channel in RPC call to '%s': %+v" , req .Method , err )
538451 stats .Record (ctx , metrics .RPCResponseError .M (1 ))
539- respErr := & respError {
452+
453+ respErr := & JSONRPCError {
540454 Code : 1 ,
541455 Message : err .Error (),
542456 }
543457
544- var ed ErrorWithData
545- if errors .As (err , & ed ) {
546- respErr .Data = ed .ErrorData ()
458+ if m , ok := err .(ErrorCodec ); ok {
459+ respErr , err := m .ToJSONRPCError ()
460+ if err != nil {
461+ log .Warnf ("Failed to convert error to JSONRPCError: %v" , err )
462+ } else {
463+ resp .Error .Data = respErr .Data
464+ }
547465 }
548466
549467 resp .Error = respErr
0 commit comments