1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 // this file contains the go forms of the wire specification
13 // see http://www.jsonrpc.org/specification for details
16 // ErrUnknown should be used for all non coded errors.
17 ErrUnknown = NewError(-32001, "JSON RPC unknown error")
18 // ErrParse is used when invalid JSON was received by the server.
19 ErrParse = NewError(-32700, "JSON RPC parse error")
20 //ErrInvalidRequest is used when the JSON sent is not a valid Request object.
21 ErrInvalidRequest = NewError(-32600, "JSON RPC invalid request")
22 // ErrMethodNotFound should be returned by the handler when the method does
23 // not exist / is not available.
24 ErrMethodNotFound = NewError(-32601, "JSON RPC method not found")
25 // ErrInvalidParams should be returned by the handler when method
26 // parameter(s) were invalid.
27 ErrInvalidParams = NewError(-32602, "JSON RPC invalid params")
28 // ErrInternal is not currently returned but defined for completeness.
29 ErrInternal = NewError(-32603, "JSON RPC internal error")
31 //ErrServerOverloaded is returned when a message was refused due to a
32 //server being temporarily unable to accept any new messages.
33 ErrServerOverloaded = NewError(-32000, "JSON RPC overloaded")
36 // wireRequest is sent to a server to represent a Call or Notify operaton.
37 type wireRequest struct {
38 // VersionTag is always encoded as the string "2.0"
39 VersionTag wireVersionTag `json:"jsonrpc"`
40 // Method is a string containing the method name to invoke.
41 Method string `json:"method"`
42 // Params is either a struct or an array with the parameters of the method.
43 Params *json.RawMessage `json:"params,omitempty"`
44 // The id of this request, used to tie the Response back to the request.
45 // Will be either a string or a number. If not set, the Request is a notify,
46 // and no response is possible.
47 ID *ID `json:"id,omitempty"`
50 // WireResponse is a reply to a Request.
51 // It will always have the ID field set to tie it back to a request, and will
52 // have either the Result or Error fields set depending on whether it is a
53 // success or failure response.
54 type wireResponse struct {
55 // VersionTag is always encoded as the string "2.0"
56 VersionTag wireVersionTag `json:"jsonrpc"`
57 // Result is the response value, and is required on success.
58 Result *json.RawMessage `json:"result,omitempty"`
59 // Error is a structured error response if the call fails.
60 Error *wireError `json:"error,omitempty"`
61 // ID must be set and is the identifier of the Request this is a response to.
62 ID *ID `json:"id,omitempty"`
65 // wireCombined has all the fields of both Request and Response.
66 // We can decode this and then work out which it is.
67 type wireCombined struct {
68 VersionTag wireVersionTag `json:"jsonrpc"`
69 ID *ID `json:"id,omitempty"`
70 Method string `json:"method"`
71 Params *json.RawMessage `json:"params,omitempty"`
72 Result *json.RawMessage `json:"result,omitempty"`
73 Error *wireError `json:"error,omitempty"`
76 // wireError represents a structured error in a Response.
77 type wireError struct {
78 // Code is an error code indicating the type of failure.
79 Code int64 `json:"code"`
80 // Message is a short description of the error.
81 Message string `json:"message"`
82 // Data is optional structured data containing additional information about the error.
83 Data *json.RawMessage `json:"data,omitempty"`
86 // wireVersionTag is a special 0 sized struct that encodes as the jsonrpc version
88 // It will fail during decode if it is not the correct version tag in the
90 type wireVersionTag struct{}
92 // ID is a Request identifier.
98 func NewError(code int64, message string) error {
105 func (err *wireError) Error() string {
109 func (wireVersionTag) MarshalJSON() ([]byte, error) {
110 return json.Marshal("2.0")
113 func (wireVersionTag) UnmarshalJSON(data []byte) error {
115 if err := json.Unmarshal(data, &version); err != nil {
118 if version != "2.0" {
119 return fmt.Errorf("invalid RPC version %v", version)
124 // NewIntID returns a new numerical request ID.
125 func NewIntID(v int64) ID { return ID{number: v} }
127 // NewStringID returns a new string request ID.
128 func NewStringID(v string) ID { return ID{name: v} }
130 // Format writes the ID to the formatter.
131 // If the rune is q the representation is non ambiguous,
132 // string forms are quoted, number forms are preceded by a #
133 func (id ID) Format(f fmt.State, r rune) {
134 numF, strF := `%d`, `%s`
136 numF, strF = `#%d`, `%q`
140 fmt.Fprintf(f, strF, id.name)
142 fmt.Fprintf(f, numF, id.number)
146 func (id *ID) MarshalJSON() ([]byte, error) {
148 return json.Marshal(id.name)
150 return json.Marshal(id.number)
153 func (id *ID) UnmarshalJSON(data []byte) error {
155 if err := json.Unmarshal(data, &id.number); err == nil {
158 return json.Unmarshal(data, &id.name)