|
|
@@ -70,6 +70,10 @@ func ParseRequest(input any) (*Request, error) {
|
|
|
return nil, fmt.Errorf("unmarshal request: %w", err)
|
|
|
}
|
|
|
|
|
|
+ if req.JSONRPC != "2.0" {
|
|
|
+ return nil, errors.New(`"jsonrpc" must be "2.0"`)
|
|
|
+ }
|
|
|
+
|
|
|
return &req, nil
|
|
|
}
|
|
|
|
|
|
@@ -93,20 +97,35 @@ func ParseResponse(input any) (*Response, error) {
|
|
|
return nil, fmt.Errorf("unmarshal response: %w", err)
|
|
|
}
|
|
|
|
|
|
+ if resp.JSONRPC != "2.0" {
|
|
|
+ return nil, errors.New(`"jsonrpc" must be "2.0"`)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 情况 1:result 和 error 同时为空 → 错误
|
|
|
if resp.Error == nil && resp.Result == nil {
|
|
|
return nil, errors.New(`response must contain either "result" or "error" field`)
|
|
|
}
|
|
|
|
|
|
+ // 情况 2:result 和 error 同时存在 → 错误
|
|
|
if resp.Error != nil && resp.Result != nil {
|
|
|
return nil, errors.New(`response can't contain both "result" and "error" field`)
|
|
|
}
|
|
|
|
|
|
- if resp.Error != nil && resp.ID == nil && resp.Error.Code != ErrParse {
|
|
|
- return nil, errors.New(`"error" must contain an "id" field`)
|
|
|
+ // 情况 3:成功时的应答 → 必须有id&且不能空
|
|
|
+ if resp.Result != nil {
|
|
|
+ if resp.ID == nil {
|
|
|
+ return nil, errors.New(`"id" must exist and cannot be null for successful response`)
|
|
|
+ }
|
|
|
+ return &resp, nil
|
|
|
}
|
|
|
|
|
|
- if resp.Result != nil && resp.ID == nil {
|
|
|
- return nil, errors.New(`"result" must contain an "id" field`)
|
|
|
+ // 情况 4:错误时的应答 → 必须有id&且不能空
|
|
|
+ if resp.Error.Code == ErrParse { // 特例: Parse error (-32700)时
|
|
|
+ return &resp, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if resp.ID == nil {
|
|
|
+ return nil, errors.New(`"id" must exist and cannot be null for error response`)
|
|
|
}
|
|
|
|
|
|
return &resp, nil
|
|
|
@@ -131,7 +150,7 @@ func marshalJSON(input any) (json.RawMessage, error) {
|
|
|
}
|
|
|
|
|
|
// 构建一个请求
|
|
|
-func BuildRequest(method string, params any, id int) (*Request, error) {
|
|
|
+func BuildRequest(method string, params any, id ...int) (*Request, error) {
|
|
|
if method == "" {
|
|
|
return nil, errors.New("method must be non-empty")
|
|
|
}
|
|
|
@@ -141,10 +160,17 @@ func BuildRequest(method string, params any, id int) (*Request, error) {
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
+ var rid int
|
|
|
+ if len(id) > 0 {
|
|
|
+ rid = id[0]
|
|
|
+ } else {
|
|
|
+ rid = nextID()
|
|
|
+ }
|
|
|
+
|
|
|
req := &Request{
|
|
|
JSONRPC: "2.0",
|
|
|
Method: method,
|
|
|
- ID: &id,
|
|
|
+ ID: &rid,
|
|
|
}
|
|
|
|
|
|
if raw != nil { // 非空参数
|
|
|
@@ -203,13 +229,13 @@ func BuildResult(req *Request, result any) (*Response, error) {
|
|
|
func BuildError(req *Request, code ErrCode, message string) *Response {
|
|
|
id := (*int)(nil)
|
|
|
|
|
|
- if code != ErrParse && req != nil && req.ID != nil {
|
|
|
+ if req != nil {
|
|
|
id = req.ID
|
|
|
}
|
|
|
|
|
|
- emsg, ok := errMessages[code]
|
|
|
- if !ok {
|
|
|
- emsg = message
|
|
|
+ emsg := message
|
|
|
+ if emsg == "" {
|
|
|
+ emsg = errMessages[code]
|
|
|
}
|
|
|
|
|
|
return &Response{
|