...

Source file src/go.etcd.io/etcd/server/v3/etcdserver/api/v2error/error.go

Documentation: go.etcd.io/etcd/server/v3/etcdserver/api/v2error

     1  // Copyright 2015 The etcd Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package v2error describes errors in etcd project. When any change happens,
    16  // https://github.com/etcd-io/website/blob/main/content/docs/v2/errorcode.md
    17  // needs to be updated correspondingly.
    18  // To be deprecated in favor of v3 APIs.
    19  package v2error
    20  
    21  import (
    22  	"encoding/json"
    23  	"fmt"
    24  	"net/http"
    25  )
    26  
    27  var errors = map[int]string{
    28  	// command related errors
    29  	EcodeKeyNotFound:      "Key not found",
    30  	EcodeTestFailed:       "Compare failed", //test and set
    31  	EcodeNotFile:          "Not a file",
    32  	ecodeNoMorePeer:       "Reached the max number of peers in the cluster",
    33  	EcodeNotDir:           "Not a directory",
    34  	EcodeNodeExist:        "Key already exists", // create
    35  	ecodeKeyIsPreserved:   "The prefix of given key is a keyword in etcd",
    36  	EcodeRootROnly:        "Root is read only",
    37  	EcodeDirNotEmpty:      "Directory not empty",
    38  	ecodeExistingPeerAddr: "Peer address has existed",
    39  	EcodeUnauthorized:     "The request requires user authentication",
    40  
    41  	// Post form related errors
    42  	ecodeValueRequired:        "Value is Required in POST form",
    43  	EcodePrevValueRequired:    "PrevValue is Required in POST form",
    44  	EcodeTTLNaN:               "The given TTL in POST form is not a number",
    45  	EcodeIndexNaN:             "The given index in POST form is not a number",
    46  	ecodeValueOrTTLRequired:   "Value or TTL is required in POST form",
    47  	ecodeTimeoutNaN:           "The given timeout in POST form is not a number",
    48  	ecodeNameRequired:         "Name is required in POST form",
    49  	ecodeIndexOrValueRequired: "Index or value is required",
    50  	ecodeIndexValueMutex:      "Index and value cannot both be specified",
    51  	EcodeInvalidField:         "Invalid field",
    52  	EcodeInvalidForm:          "Invalid POST form",
    53  	EcodeRefreshValue:         "Value provided on refresh",
    54  	EcodeRefreshTTLRequired:   "A TTL must be provided on refresh",
    55  
    56  	// raft related errors
    57  	EcodeRaftInternal: "Raft Internal Error",
    58  	EcodeLeaderElect:  "During Leader Election",
    59  
    60  	// etcd related errors
    61  	EcodeWatcherCleared:     "watcher is cleared due to etcd recovery",
    62  	EcodeEventIndexCleared:  "The event in requested index is outdated and cleared",
    63  	ecodeStandbyInternal:    "Standby Internal Error",
    64  	ecodeInvalidActiveSize:  "Invalid active size",
    65  	ecodeInvalidRemoveDelay: "Standby remove delay",
    66  
    67  	// client related errors
    68  	ecodeClientInternal: "Client Internal Error",
    69  }
    70  
    71  var errorStatus = map[int]int{
    72  	EcodeKeyNotFound:  http.StatusNotFound,
    73  	EcodeNotFile:      http.StatusForbidden,
    74  	EcodeDirNotEmpty:  http.StatusForbidden,
    75  	EcodeUnauthorized: http.StatusUnauthorized,
    76  	EcodeTestFailed:   http.StatusPreconditionFailed,
    77  	EcodeNodeExist:    http.StatusPreconditionFailed,
    78  	EcodeRaftInternal: http.StatusInternalServerError,
    79  	EcodeLeaderElect:  http.StatusInternalServerError,
    80  }
    81  
    82  const (
    83  	EcodeKeyNotFound      = 100
    84  	EcodeTestFailed       = 101
    85  	EcodeNotFile          = 102
    86  	ecodeNoMorePeer       = 103
    87  	EcodeNotDir           = 104
    88  	EcodeNodeExist        = 105
    89  	ecodeKeyIsPreserved   = 106
    90  	EcodeRootROnly        = 107
    91  	EcodeDirNotEmpty      = 108
    92  	ecodeExistingPeerAddr = 109
    93  	EcodeUnauthorized     = 110
    94  
    95  	ecodeValueRequired        = 200
    96  	EcodePrevValueRequired    = 201
    97  	EcodeTTLNaN               = 202
    98  	EcodeIndexNaN             = 203
    99  	ecodeValueOrTTLRequired   = 204
   100  	ecodeTimeoutNaN           = 205
   101  	ecodeNameRequired         = 206
   102  	ecodeIndexOrValueRequired = 207
   103  	ecodeIndexValueMutex      = 208
   104  	EcodeInvalidField         = 209
   105  	EcodeInvalidForm          = 210
   106  	EcodeRefreshValue         = 211
   107  	EcodeRefreshTTLRequired   = 212
   108  
   109  	EcodeRaftInternal = 300
   110  	EcodeLeaderElect  = 301
   111  
   112  	EcodeWatcherCleared     = 400
   113  	EcodeEventIndexCleared  = 401
   114  	ecodeStandbyInternal    = 402
   115  	ecodeInvalidActiveSize  = 403
   116  	ecodeInvalidRemoveDelay = 404
   117  
   118  	ecodeClientInternal = 500
   119  )
   120  
   121  type Error struct {
   122  	ErrorCode int    `json:"errorCode"`
   123  	Message   string `json:"message"`
   124  	Cause     string `json:"cause,omitempty"`
   125  	Index     uint64 `json:"index"`
   126  }
   127  
   128  func NewRequestError(errorCode int, cause string) *Error {
   129  	return NewError(errorCode, cause, 0)
   130  }
   131  
   132  func NewError(errorCode int, cause string, index uint64) *Error {
   133  	return &Error{
   134  		ErrorCode: errorCode,
   135  		Message:   errors[errorCode],
   136  		Cause:     cause,
   137  		Index:     index,
   138  	}
   139  }
   140  
   141  // Error is for the error interface
   142  func (e Error) Error() string {
   143  	return e.Message + " (" + e.Cause + ")"
   144  }
   145  
   146  func (e Error) toJsonString() string {
   147  	b, _ := json.Marshal(e)
   148  	return string(b)
   149  }
   150  
   151  func (e Error) StatusCode() int {
   152  	status, ok := errorStatus[e.ErrorCode]
   153  	if !ok {
   154  		status = http.StatusBadRequest
   155  	}
   156  	return status
   157  }
   158  
   159  func (e Error) WriteTo(w http.ResponseWriter) error {
   160  	w.Header().Add("X-Etcd-Index", fmt.Sprint(e.Index))
   161  	w.Header().Set("Content-Type", "application/json")
   162  	w.WriteHeader(e.StatusCode())
   163  	_, err := w.Write([]byte(e.toJsonString() + "\n"))
   164  	return err
   165  }
   166  

View as plain text