PageRenderTime 1ms CodeModel.GetById 14ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/error/error.go

https://github.com/jovibizstack/etcd
Go | 148 lines | 108 code | 18 blank | 22 comment | 3 complexity | 6657c5fc12fafe79fa23957562b30b4a MD5 | raw file
  1/*
  2Copyright 2013 CoreOS Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8     http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15*/
 16
 17package error
 18
 19import (
 20	"encoding/json"
 21	"fmt"
 22	"net/http"
 23)
 24
 25var errors = map[int]string{
 26	// command related errors
 27	EcodeKeyNotFound:      "Key not found",
 28	EcodeTestFailed:       "Compare failed", //test and set
 29	EcodeNotFile:          "Not a file",
 30	EcodeNoMorePeer:       "Reached the max number of peers in the cluster",
 31	EcodeNotDir:           "Not a directory",
 32	EcodeNodeExist:        "Key already exists", // create
 33	EcodeRootROnly:        "Root is read only",
 34	EcodeKeyIsPreserved:   "The prefix of given key is a keyword in etcd",
 35	EcodeDirNotEmpty:      "Directory not empty",
 36	EcodeExistingPeerAddr: "Peer address has existed",
 37
 38	// Post form related errors
 39	EcodeValueRequired:        "Value is Required in POST form",
 40	EcodePrevValueRequired:    "PrevValue is Required in POST form",
 41	EcodeTTLNaN:               "The given TTL in POST form is not a number",
 42	EcodeIndexNaN:             "The given index in POST form is not a number",
 43	EcodeValueOrTTLRequired:   "Value or TTL is required in POST form",
 44	EcodeTimeoutNaN:           "The given timeout in POST form is not a number",
 45	EcodeNameRequired:         "Name is required in POST form",
 46	EcodeIndexOrValueRequired: "Index or value is required",
 47	EcodeIndexValueMutex:      "Index and value cannot both be specified",
 48	EcodeInvalidField:         "Invalid field",
 49
 50	// raft related errors
 51	EcodeRaftInternal: "Raft Internal Error",
 52	EcodeLeaderElect:  "During Leader Election",
 53
 54	// etcd related errors
 55	EcodeWatcherCleared:     "watcher is cleared due to etcd recovery",
 56	EcodeEventIndexCleared:  "The event in requested index is outdated and cleared",
 57	EcodeStandbyInternal:    "Standby Internal Error",
 58	EcodeInvalidActiveSize:  "Invalid active size",
 59	EcodeInvalidRemoveDelay: "Standby remove delay",
 60
 61	// client related errors
 62	EcodeClientInternal: "Client Internal Error",
 63}
 64
 65const (
 66	EcodeKeyNotFound      = 100
 67	EcodeTestFailed       = 101
 68	EcodeNotFile          = 102
 69	EcodeNoMorePeer       = 103
 70	EcodeNotDir           = 104
 71	EcodeNodeExist        = 105
 72	EcodeKeyIsPreserved   = 106
 73	EcodeRootROnly        = 107
 74	EcodeDirNotEmpty      = 108
 75	EcodeExistingPeerAddr = 109
 76
 77	EcodeValueRequired        = 200
 78	EcodePrevValueRequired    = 201
 79	EcodeTTLNaN               = 202
 80	EcodeIndexNaN             = 203
 81	EcodeValueOrTTLRequired   = 204
 82	EcodeTimeoutNaN           = 205
 83	EcodeNameRequired         = 206
 84	EcodeIndexOrValueRequired = 207
 85	EcodeIndexValueMutex      = 208
 86	EcodeInvalidField         = 209
 87
 88	EcodeRaftInternal = 300
 89	EcodeLeaderElect  = 301
 90
 91	EcodeWatcherCleared     = 400
 92	EcodeEventIndexCleared  = 401
 93	EcodeStandbyInternal    = 402
 94	EcodeInvalidActiveSize  = 403
 95	EcodeInvalidRemoveDelay = 404
 96
 97	EcodeClientInternal = 500
 98)
 99
100type Error struct {
101	ErrorCode int    `json:"errorCode"`
102	Message   string `json:"message"`
103	Cause     string `json:"cause,omitempty"`
104	Index     uint64 `json:"index"`
105}
106
107func NewError(errorCode int, cause string, index uint64) *Error {
108	return &Error{
109		ErrorCode: errorCode,
110		Message:   errors[errorCode],
111		Cause:     cause,
112		Index:     index,
113	}
114}
115
116func Message(code int) string {
117	return errors[code]
118}
119
120// Only for error interface
121func (e Error) Error() string {
122	return e.Message + " (" + e.Cause + ")"
123}
124
125func (e Error) toJsonString() string {
126	b, _ := json.Marshal(e)
127	return string(b)
128}
129
130func (e Error) Write(w http.ResponseWriter) {
131	w.Header().Add("X-Etcd-Index", fmt.Sprint(e.Index))
132	// 3xx is raft internal error
133	status := http.StatusBadRequest
134	switch e.ErrorCode {
135	case EcodeKeyNotFound:
136		status = http.StatusNotFound
137	case EcodeNotFile, EcodeDirNotEmpty:
138		status = http.StatusForbidden
139	case EcodeTestFailed, EcodeNodeExist:
140		status = http.StatusPreconditionFailed
141	default:
142		if e.ErrorCode/100 == 3 {
143			status = http.StatusInternalServerError
144		}
145	}
146	w.WriteHeader(status)
147	fmt.Fprintln(w, e.toJsonString())
148}