-
Notifications
You must be signed in to change notification settings - Fork 98
feat: add 'Data' field to 'respError' struct #123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 13 commits
d56a7d5
8493164
dfc83a0
514c1af
a0806e5
53eab64
4358258
4e33c9f
9592989
65441ad
ef506b1
e8dc77a
90c8605
9ef484a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -65,71 +65,6 @@ type request struct { | |
| // Configured by WithMaxRequestSize. | ||
| const DEFAULT_MAX_REQUEST_SIZE = 100 << 20 // 100 MiB | ||
|
|
||
| type respError struct { | ||
| Code ErrorCode `json:"code"` | ||
| Message string `json:"message"` | ||
| Meta json.RawMessage `json:"meta,omitempty"` | ||
| } | ||
|
|
||
| func (e *respError) Error() string { | ||
| if e.Code >= -32768 && e.Code <= -32000 { | ||
| return fmt.Sprintf("RPC error (%d): %s", e.Code, e.Message) | ||
| } | ||
| return e.Message | ||
| } | ||
|
|
||
| var marshalableRT = reflect.TypeOf(new(marshalable)).Elem() | ||
|
|
||
| func (e *respError) val(errors *Errors) reflect.Value { | ||
| if errors != nil { | ||
| t, ok := errors.byCode[e.Code] | ||
| if ok { | ||
| var v reflect.Value | ||
| if t.Kind() == reflect.Ptr { | ||
| v = reflect.New(t.Elem()) | ||
| } else { | ||
| v = reflect.New(t) | ||
| } | ||
| if len(e.Meta) > 0 && v.Type().Implements(marshalableRT) { | ||
| _ = v.Interface().(marshalable).UnmarshalJSON(e.Meta) | ||
| } | ||
| if t.Kind() != reflect.Ptr { | ||
| v = v.Elem() | ||
| } | ||
| return v | ||
| } | ||
| } | ||
|
|
||
| return reflect.ValueOf(e) | ||
| } | ||
|
|
||
| type response struct { | ||
| Jsonrpc string | ||
| Result interface{} | ||
| ID interface{} | ||
| Error *respError | ||
| } | ||
|
|
||
| func (r response) MarshalJSON() ([]byte, error) { | ||
| // Custom marshal logic as per JSON-RPC 2.0 spec: | ||
| // > `result`: | ||
| // > This member is REQUIRED on success. | ||
| // > This member MUST NOT exist if there was an error invoking the method. | ||
| // | ||
| // > `error`: | ||
| // > This member is REQUIRED on error. | ||
| // > This member MUST NOT exist if there was no error triggered during invocation. | ||
| data := make(map[string]interface{}) | ||
| data["jsonrpc"] = r.Jsonrpc | ||
| data["id"] = r.ID | ||
| if r.Error != nil { | ||
| data["error"] = r.Error | ||
| } else { | ||
| data["result"] = r.Result | ||
| } | ||
| return json.Marshal(data) | ||
| } | ||
|
|
||
| type handler struct { | ||
| methods map[string]methodHandler | ||
| errors *Errors | ||
|
|
@@ -334,7 +269,7 @@ func (s *handler) getSpan(ctx context.Context, req request) (context.Context, *t | |
| return ctx, span | ||
| } | ||
|
|
||
| func (s *handler) createError(err error) *respError { | ||
| func (s *handler) createError(err error) *JSONRPCError { | ||
| var code ErrorCode = 1 | ||
| if s.errors != nil { | ||
| c, ok := s.errors.byType[reflect.TypeOf(err)] | ||
|
|
@@ -343,15 +278,25 @@ func (s *handler) createError(err error) *respError { | |
| } | ||
| } | ||
|
|
||
| out := &respError{ | ||
| out := &JSONRPCError{ | ||
| Code: code, | ||
| Message: err.Error(), | ||
| } | ||
|
|
||
| if m, ok := err.(marshalable); ok { | ||
| meta, err := m.MarshalJSON() | ||
| if err == nil { | ||
| switch m := err.(type) { | ||
| case RPCErrorCodec: | ||
| o, err := m.ToJSONRPCError() | ||
| if err != nil { | ||
| log.Warnf("Failed to convert error to JSONRPCError: %v", err) | ||
| } else { | ||
| out = &o | ||
| } | ||
| case marshalable: | ||
| meta, marshalErr := m.MarshalJSON() | ||
| if marshalErr == nil { | ||
| out.Meta = meta | ||
| } else { | ||
| log.Warnf("Failed to marshal error metadata: %v", marshalErr) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -504,10 +449,22 @@ func (s *handler) handle(ctx context.Context, req request, w func(func(io.Writer | |
|
|
||
| log.Warnf("failed to setup channel in RPC call to '%s': %+v", req.Method, err) | ||
| stats.Record(ctx, metrics.RPCResponseError.M(1)) | ||
| resp.Error = &respError{ | ||
|
|
||
| respErr := &JSONRPCError{ | ||
| Code: 1, | ||
| Message: err.Error(), | ||
| } | ||
|
|
||
| if m, ok := err.(RPCErrorCodec); ok { | ||
| rpcErr, err := m.ToJSONRPCError() | ||
| if err != nil { | ||
| log.Warnf("Failed to convert error to JSONRPCError: %v", err) | ||
| } else { | ||
| respErr.Data = rpcErr.Data | ||
| } | ||
| } | ||
|
|
||
| resp.Error = respErr | ||
|
||
| } else { | ||
| resp.Result = res | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's
Errorfthese two as well, if they're not converting then it's either a programmer error or a system error (like OOM)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.