errors.go
package tezos
import (
"encoding/json"
"fmt"
"net/http"
)
const (
// ErrorKindPermanent Tezos RPC error kind.
ErrorKindPermanent = "permanent"
// ErrorKindTemporary Tezos RPC error kind.
ErrorKindTemporary = "temporary"
// ErrorKindBranch Tezos RPC error kind.
ErrorKindBranch = "branch"
)
// Error is a Tezos error as documented on http://tezos.gitlab.io/mainnet/api/errors.html.
type Error interface {
error
ErrorID() string
ErrorKind() string
}
// GenericError is a basic error type
type GenericError struct {
ID string `json:"id"`
Kind string `json:"kind"`
}
func (e *GenericError) Error() string {
return fmt.Sprintf("tezos: kind = %q, id = %q", e.Kind, e.ID)
}
// ErrorID returns Tezos error id
func (e *GenericError) ErrorID() string {
return e.ID
}
// ErrorKind returns Tezos error kind
func (e *GenericError) ErrorKind() string {
return e.Kind
}
// HTTPStatus interface represents an unprocessed HTTP reply
type HTTPStatus interface {
Response() *http.Response
Status() string // e.g. "200 OK"
StatusCode() int // e.g. 200
Body() []byte
}
// HTTPError retains HTTP status
type HTTPError interface {
error
HTTPStatus
}
// RPCError is a Tezos RPC error as documented on http://tezos.gitlab.io/mainnet/api/errors.html.
type RPCError interface {
Error
HTTPStatus
Errors() []Error // returns all errors as a slice
}
// Errors is a slice of Error with custom JSON unmarshaller
type Errors []Error
// UnmarshalJSON implements json.Unmarshaler
func (e *Errors) UnmarshalJSON(data []byte) error {
var errs []*GenericError
if err := json.Unmarshal(data, &errs); err != nil {
return err
}
*e = make(Errors, len(errs))
for i, g := range errs {
// TODO: handle different kinds
(*e)[i] = g
}
return nil
}
func (e Errors) Error() string {
if len(e) == 0 {
return ""
}
return e[0].Error()
}
// ErrorID returns Tezos error id
func (e Errors) ErrorID() string {
if len(e) == 0 {
return ""
}
return e[0].ErrorID()
}
// ErrorKind returns Tezos error kind
func (e Errors) ErrorKind() string {
if len(e) == 0 {
return ""
}
return e[0].ErrorKind()
}
type httpError struct {
response *http.Response
body []byte
}
func (e *httpError) Error() string {
return fmt.Sprintf("tezos: HTTP status %v", e.response.StatusCode)
}
func (e *httpError) Status() string {
return e.response.Status
}
func (e *httpError) StatusCode() int {
return e.response.StatusCode
}
func (e *httpError) Body() []byte {
return e.body
}
func (e *httpError) Response() *http.Response {
return e.response
}
type rpcError struct {
*httpError
errors Errors
}
func (e *rpcError) Error() string {
return e.errors.Error()
}
func (e *rpcError) ErrorID() string {
return e.errors.ErrorID()
}
func (e *rpcError) ErrorKind() string {
return e.errors.ErrorKind()
}
func (e *rpcError) Errors() []Error {
return e.errors
}
type plainError struct {
*httpError
msg string
}
func (e *plainError) Error() string {
return e.msg
}
var (
_ Error = &GenericError{}
_ Error = Errors{}
_ RPCError = &rpcError{}
)