error.go raw

   1  // Copyright 2018 Adam S Levy
   2  //
   3  // Permission is hereby granted, free of charge, to any person obtaining a copy
   4  // of this software and associated documentation files (the "Software"), to
   5  // deal in the Software without restriction, including without limitation the
   6  // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
   7  // sell copies of the Software, and to permit persons to whom the Software is
   8  // furnished to do so, subject to the following conditions:
   9  //
  10  // The above copyright notice and this permission notice shall be included in
  11  // all copies or substantial portions of the Software.
  12  //
  13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18  // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  19  // IN THE SOFTWARE.
  20  
  21  package jsonrpc2
  22  
  23  import "fmt"
  24  
  25  // ErrorCode indicates the Error type that occurred.
  26  //
  27  // The error codes from and including -32768 to -32000 are reserved for
  28  // pre-defined errors. Any code within this range, but not defined explicitly
  29  // below is reserved for future use.
  30  //
  31  // See ErrorCodeMinReserved.
  32  type ErrorCode int
  33  
  34  // Official JSON-RPC 2.0 Spec Error Codes and Messages
  35  const (
  36  	// ErrorCodeMinReserved is the minimum reserved error code. Method
  37  	// defined errors may be less than this value.
  38  	ErrorCodeMinReserved ErrorCode = -32768
  39  
  40  	// ErrorCodeParse means the received data was not valid JSON.
  41  	ErrorCodeParse    ErrorCode = -32700
  42  	ErrorMessageParse           = "Parse error"
  43  
  44  	// ErrorCodeInvalidRequest means the received valid JSON is not a valid
  45  	// Request object.
  46  	ErrorCodeInvalidRequest    ErrorCode = -32600
  47  	ErrorMessageInvalidRequest           = "Invalid Request"
  48  
  49  	// ErrorCodeMethodNotFound means the requested method is not defined
  50  	// for the HTTPRequestHandler.
  51  	ErrorCodeMethodNotFound    ErrorCode = -32601
  52  	ErrorMessageMethodNotFound           = "Method not found"
  53  
  54  	// ErrorCodeInvalidParams means a method is called with invalid method
  55  	// parameter(s).
  56  	//
  57  	// MethodFuncs are responsible for detecting and returning this error.
  58  	ErrorCodeInvalidParams    ErrorCode = -32602
  59  	ErrorMessageInvalidParams           = "Invalid params"
  60  
  61  	// ErrorCodeInternal means an internal error occurred such as a
  62  	// MethodFunc panic.
  63  	ErrorCodeInternal    ErrorCode = -32603
  64  	ErrorMessageInternal           = "Internal error"
  65  
  66  	// ErrorCodeMaxReserved is the maximum reserved error code. Method
  67  	// defined errors may be greater than this value.
  68  	ErrorCodeMaxReserved ErrorCode = -32000
  69  )
  70  
  71  // IsReserved returns true if c is within the reserved error code range:
  72  //      [LowestReservedErrorCode, HighestReservedErrorCode]
  73  func (c ErrorCode) IsReserved() bool {
  74  	return ErrorCodeMinReserved <= c && c <= ErrorCodeMaxReserved
  75  }
  76  
  77  func (c ErrorCode) String() string {
  78  	if !c.IsReserved() {
  79  		return fmt.Sprintf("ErrorCode{%v}", int(c))
  80  	}
  81  	msg := "reserved"
  82  	switch c {
  83  	case ErrorCodeParse:
  84  		msg = ErrorMessageParse
  85  	case ErrorCodeInvalidRequest:
  86  		msg = ErrorMessageInvalidRequest
  87  	case ErrorCodeMethodNotFound:
  88  		msg = ErrorMessageMethodNotFound
  89  	case ErrorCodeInvalidParams:
  90  		msg = ErrorMessageInvalidParams
  91  	case ErrorCodeInternal:
  92  		msg = ErrorMessageInternal
  93  	}
  94  	return fmt.Sprintf("ErrorCode{%v:%q}", int(c), msg)
  95  }
  96  
  97  // Error represents a JSON-RPC 2.0 Error object, which is used in the Response
  98  // object. MethodFuncs may return an Error or *Error to return an Error
  99  // Response to the client.
 100  type Error struct {
 101  	// Code is a number that indicates the error type that occurred.
 102  	Code ErrorCode `json:"code"`
 103  
 104  	// Message is a short description of the error. The message SHOULD be
 105  	// limited to a concise single sentence.
 106  	Message string `json:"message"`
 107  
 108  	// Data is a Primitive or Structured value that contains additional
 109  	// information about the error. This may be omitted. The value of this
 110  	// member is defined by the Server (e.g. detailed error information,
 111  	// nested errors etc.).
 112  	Data interface{} `json:"data,omitempty"`
 113  }
 114  
 115  // Error implements the error interface.
 116  func (e Error) Error() string {
 117  	s := fmt.Sprintf("jsonrpc2.Error{Code:%v, Message:%q", e.Code, e.Message)
 118  	if e.Data != nil {
 119  		s += fmt.Sprintf(", Data:%#v", e.Data)
 120  	}
 121  	return s + "}"
 122  }
 123  
 124  // IsZero reports whether e is zero valued.
 125  func (e Error) IsZero() bool {
 126  	return e == Error{}
 127  }
 128  
 129  // NewError returns an Error with code, msg, and data.
 130  //
 131  // The data must not cause an error when passed to json.Marshal, else any
 132  // MethodFunc returning it will return an Internal Error to clients instead.
 133  //
 134  // If data is type error, then the Error() string is used instead, since
 135  // otherwise the error may not json.Marshal properly.
 136  func NewError(code ErrorCode, msg string, data interface{}) Error {
 137  	if err, ok := data.(error); ok {
 138  		data = err.Error()
 139  	}
 140  	return Error{code, msg, data}
 141  }
 142  
 143  // ErrorInvalidParams returns
 144  //      NewError(ErrorCodeInvalidParams, ErrorMessageInvalidParams, data)
 145  //
 146  // MethodFuncs are responsible for detecting invalid parameters and returning
 147  // this error.
 148  func ErrorInvalidParams(data interface{}) Error {
 149  	return NewError(ErrorCodeInvalidParams, ErrorMessageInvalidParams, data)
 150  }
 151  
 152  func errorInternal(data interface{}) Error {
 153  	return NewError(ErrorCodeInternal, ErrorMessageInternal, data)
 154  }
 155  func errorParse(data interface{}) Error {
 156  	return NewError(ErrorCodeParse, ErrorMessageParse, data)
 157  }
 158  func errorInvalidRequest(data interface{}) Error {
 159  	return NewError(ErrorCodeInvalidRequest, ErrorMessageInvalidRequest, data)
 160  }
 161  func errorMethodNotFound(data interface{}) Error {
 162  	return NewError(ErrorCodeMethodNotFound, ErrorMessageMethodNotFound, data)
 163  }
 164