code.vegaprotocol.io/vega@v0.79.0/libs/jsonrpc/response.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package jsonrpc
    17  
    18  import "fmt"
    19  
    20  // Result is just a nicer way to describe what's expected to be returned by the
    21  // handlers.
    22  type Result interface{}
    23  
    24  type Response struct {
    25  	// Version specifies the version of the JSON-RPC protocol.
    26  	// MUST be exactly "2.0".
    27  	Version string `json:"jsonrpc"`
    28  
    29  	// Result is REQUIRED on success. This member MUST NOT exist if there was an
    30  	// error invoking the method.
    31  	Result Result `json:"result,omitempty"`
    32  
    33  	// Error is REQUIRED on error. This member MUST NOT exist if there was no
    34  	// error triggered during invocation.
    35  	Error *ErrorDetails `json:"error,omitempty"`
    36  
    37  	// ID is an identifier established by the Client that MUST contain a String.
    38  	// This member is REQUIRED. It MUST be the same as the value of the id member
    39  	// in the Request Object.
    40  	// If there was an error in detecting the id in the Request object (e.g.
    41  	// Parse error/Invalid Request), it MUST be empty.
    42  	ID string `json:"id,omitempty"`
    43  }
    44  
    45  type ErrorCode int16
    46  
    47  const (
    48  	// ErrorCodeParseError Invalid JSON was received by the server. An error
    49  	// occurred on the server while parsing the JSON text.
    50  	ErrorCodeParseError ErrorCode = -32700
    51  	// ErrorCodeInvalidRequest The JSON sent is not a valid Request object.
    52  	ErrorCodeInvalidRequest ErrorCode = -32600
    53  	// ErrorCodeMethodNotFound The method does not exist / is not available.
    54  	ErrorCodeMethodNotFound ErrorCode = -32601
    55  	// ErrorCodeInvalidParams Invalid method parameter(s).
    56  	ErrorCodeInvalidParams ErrorCode = -32602
    57  	// ErrorCodeInternalError Internal JSON-RPC error.
    58  	ErrorCodeInternalError ErrorCode = -32603
    59  
    60  	// Implementation-defined server-errors.
    61  	// -32000 to -32099 codes are reserved for implementation-defined server-errors.
    62  	// See https://www.jsonrpc.org/specification#error_object for more information.
    63  
    64  	// ErrorCodeServerError is a generic implementation-defined server error.
    65  	// This can be used when error that does not cleanly map to the error codes
    66  	// above occurs in the server.
    67  	ErrorCodeServerError ErrorCode = -32000
    68  )
    69  
    70  // ErrorDetails is returned when an RPC call encounters an error.
    71  type ErrorDetails struct {
    72  	// Code indicates the error type that occurred.
    73  	Code ErrorCode `json:"code"`
    74  
    75  	// Message provides a short description of the error.
    76  	// The message SHOULD be limited to a concise single sentence.
    77  	Message string `json:"message"`
    78  
    79  	// Data is a primitive or a structured value that contains additional
    80  	// information about the error. This may be omitted.
    81  	// The value of this member is defined by the Server (e.g. detailed error
    82  	// information, nested errors etc.).
    83  	Data string `json:"data,omitempty"`
    84  }
    85  
    86  func (d ErrorDetails) IsInternalError() bool {
    87  	return d.Message == "Internal error"
    88  }
    89  
    90  func (d ErrorDetails) Error() string {
    91  	return fmt.Sprintf("%s (%s %d)", d.Data, d.Message, d.Code)
    92  }
    93  
    94  func NewParseError(data error) *ErrorDetails {
    95  	return &ErrorDetails{
    96  		Code:    ErrorCodeParseError,
    97  		Message: "Parse error",
    98  		Data:    data.Error(),
    99  	}
   100  }
   101  
   102  func NewInvalidRequest(data error) *ErrorDetails {
   103  	return &ErrorDetails{
   104  		Code:    ErrorCodeInvalidRequest,
   105  		Message: "Invalid Request",
   106  		Data:    data.Error(),
   107  	}
   108  }
   109  
   110  func NewMethodNotFound(methodName string) *ErrorDetails {
   111  	return &ErrorDetails{
   112  		Code:    ErrorCodeMethodNotFound,
   113  		Message: "Method not found",
   114  		Data:    fmt.Sprintf("method %q is not supported", methodName),
   115  	}
   116  }
   117  
   118  func NewUnsupportedMethod(data error) *ErrorDetails {
   119  	return &ErrorDetails{
   120  		Code:    ErrorCodeMethodNotFound,
   121  		Message: "Method not found",
   122  		Data:    data.Error(),
   123  	}
   124  }
   125  
   126  func NewInvalidParams(data error) *ErrorDetails {
   127  	return &ErrorDetails{
   128  		Code:    ErrorCodeInvalidParams,
   129  		Message: "Invalid params",
   130  		Data:    data.Error(),
   131  	}
   132  }
   133  
   134  func NewInternalError(data error) *ErrorDetails {
   135  	return &ErrorDetails{
   136  		Code:    ErrorCodeInternalError,
   137  		Message: "Internal error",
   138  		Data:    data.Error(),
   139  	}
   140  }
   141  
   142  func NewServerError(code ErrorCode, data error) *ErrorDetails {
   143  	if code > -32000 || code < -32099 {
   144  		panic("server error code should be between [-32000, -32099]")
   145  	}
   146  	return &ErrorDetails{
   147  		Code:    code,
   148  		Message: "Server error",
   149  		Data:    data.Error(),
   150  	}
   151  }
   152  
   153  func NewCustomError(code ErrorCode, message string, data error) *ErrorDetails {
   154  	if code <= -32000 {
   155  		panic("custom error code should be greater than -32000")
   156  	}
   157  	return &ErrorDetails{
   158  		Code:    code,
   159  		Message: message,
   160  		Data:    data.Error(),
   161  	}
   162  }
   163  
   164  func NewErrorResponse(id string, details *ErrorDetails) *Response {
   165  	return &Response{
   166  		Version: VERSION2,
   167  		Error:   details,
   168  		ID:      id,
   169  	}
   170  }
   171  
   172  func NewSuccessfulResponse(id string, result Result) *Response {
   173  	return &Response{
   174  		Version: VERSION2,
   175  		Result:  result,
   176  		ID:      id,
   177  	}
   178  }