error.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package error
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. )
  7. var errors map[int]string
  8. const (
  9. EcodeKeyNotFound = 100
  10. EcodeTestFailed = 101
  11. EcodeNotFile = 102
  12. EcodeNoMoreMachine = 103
  13. EcodeNotDir = 104
  14. EcodeNodeExist = 105
  15. EcodeKeyIsPreserved = 106
  16. EcodeValueRequired = 200
  17. EcodePrevValueRequired = 201
  18. EcodeTTLNaN = 202
  19. EcodeIndexNaN = 203
  20. EcodeValueOrTTLRequired = 204
  21. EcodeRaftInternal = 300
  22. EcodeLeaderElect = 301
  23. EcodeWatcherCleared = 400
  24. EcodeEventIndexCleared = 401
  25. )
  26. func init() {
  27. errors = make(map[int]string)
  28. // command related errors
  29. errors[EcodeKeyNotFound] = "Key Not Found"
  30. errors[EcodeTestFailed] = "Test Failed" //test and set
  31. errors[EcodeNotFile] = "Not A File"
  32. errors[EcodeNoMoreMachine] = "Reached the max number of machines in the cluster"
  33. errors[EcodeNotDir] = "Not A Directory"
  34. errors[EcodeNodeExist] = "Already exists" // create
  35. errors[EcodeKeyIsPreserved] = "The prefix of given key is a keyword in etcd"
  36. // Post form related errors
  37. errors[EcodeValueRequired] = "Value is Required in POST form"
  38. errors[EcodePrevValueRequired] = "PrevValue is Required in POST form"
  39. errors[EcodeTTLNaN] = "The given TTL in POST form is not a number"
  40. errors[EcodeIndexNaN] = "The given index in POST form is not a number"
  41. errors[EcodeValueOrTTLRequired] = "Value or TTL is required in POST form"
  42. // raft related errors
  43. errors[EcodeRaftInternal] = "Raft Internal Error"
  44. errors[EcodeLeaderElect] = "During Leader Election"
  45. // etcd related errors
  46. errors[EcodeWatcherCleared] = "watcher is cleared due to etcd recovery"
  47. errors[EcodeEventIndexCleared] = "The event in requested index is outdated and cleared"
  48. }
  49. type Error struct {
  50. ErrorCode int `json:"errorCode"`
  51. Message string `json:"message"`
  52. Cause string `json:"cause,omitempty"`
  53. Index uint64 `json:"index"`
  54. Term uint64 `json:"term"`
  55. }
  56. func NewError(errorCode int, cause string, index uint64, term uint64) *Error {
  57. return &Error{
  58. ErrorCode: errorCode,
  59. Message: errors[errorCode],
  60. Cause: cause,
  61. Index: index,
  62. Term: term,
  63. }
  64. }
  65. func Message(code int) string {
  66. return errors[code]
  67. }
  68. // Only for error interface
  69. func (e Error) Error() string {
  70. return e.Message
  71. }
  72. func (e Error) toJsonString() string {
  73. b, _ := json.Marshal(e)
  74. return string(b)
  75. }
  76. func (e Error) Write(w http.ResponseWriter) {
  77. w.Header().Add("X-Etcd-Index", fmt.Sprint(e.Index))
  78. w.Header().Add("X-Etcd-Term", fmt.Sprint(e.Term))
  79. // 3xx is reft internal error
  80. if e.ErrorCode/100 == 3 {
  81. http.Error(w, e.toJsonString(), http.StatusInternalServerError)
  82. } else {
  83. http.Error(w, e.toJsonString(), http.StatusBadRequest)
  84. }
  85. }