Browse Source

etcdhttp:write etcderror for all errors in keyhandler

Xiang Li 10 years ago
parent
commit
d487cf6b63
2 changed files with 25 additions and 5 deletions
  1. 23 3
      etcdserver/etcdhttp/client.go
  2. 2 2
      etcdserver/etcdhttp/client_test.go

+ 23 - 3
etcdserver/etcdhttp/client.go

@@ -131,7 +131,7 @@ func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 
 	rr, err := parseKeyRequest(r, clockwork.NewRealClock())
 	rr, err := parseKeyRequest(r, clockwork.NewRealClock())
 	if err != nil {
 	if err != nil {
-		writeError(w, err)
+		writeKeyError(w, err)
 		return
 		return
 	}
 	}
 	// The path must be valid at this point (we've parsed the request successfully).
 	// The path must be valid at this point (we've parsed the request successfully).
@@ -143,7 +143,7 @@ func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	resp, err := h.server.Do(ctx, rr)
 	resp, err := h.server.Do(ctx, rr)
 	if err != nil {
 	if err != nil {
 		err = trimErrorPrefix(err, etcdserver.StoreKeysPrefix)
 		err = trimErrorPrefix(err, etcdserver.StoreKeysPrefix)
-		writeError(w, err)
+		writeKeyError(w, err)
 		return
 		return
 	}
 	}
 	switch {
 	switch {
@@ -157,7 +157,7 @@ func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		defer cancel()
 		defer cancel()
 		handleKeyWatch(ctx, w, resp.Watcher, rr.Stream, h.timer)
 		handleKeyWatch(ctx, w, resp.Watcher, rr.Stream, h.timer)
 	default:
 	default:
-		writeError(w, errors.New("received response with no Event/Watcher!"))
+		writeKeyError(w, errors.New("received response with no Event/Watcher!"))
 	}
 	}
 }
 }
 
 
@@ -583,6 +583,26 @@ func writeKeyNoAuth(w http.ResponseWriter) {
 	e.WriteTo(w)
 	e.WriteTo(w)
 }
 }
 
 
+// writeKeyError logs and writes the given Error to the ResponseWriter.
+// If Error is not an etcdErr, the error will be converted to an etcd error.
+func writeKeyError(w http.ResponseWriter, err error) {
+	if err == nil {
+		return
+	}
+	switch e := err.(type) {
+	case *etcdErr.Error:
+		e.WriteTo(w)
+	default:
+		if err == etcdserver.ErrTimeoutDueToLeaderFail {
+			plog.Error(err)
+		} else {
+			plog.Errorf("got unexpected response error (%v)", err)
+		}
+		ee := etcdErr.NewError(etcdErr.EcodeRaftInternal, err.Error(), 0)
+		ee.WriteTo(w)
+	}
+}
+
 func handleKeyWatch(ctx context.Context, w http.ResponseWriter, wa store.Watcher, stream bool, rt etcdserver.RaftTimer) {
 func handleKeyWatch(ctx context.Context, w http.ResponseWriter, wa store.Watcher, stream bool, rt etcdserver.RaftTimer) {
 	defer wa.Remove()
 	defer wa.Remove()
 	ech := wa.EventChan()
 	ech := wa.EventChan()

+ 2 - 2
etcdserver/etcdhttp/client_test.go

@@ -1406,7 +1406,7 @@ func TestBadServeKeys(t *testing.T) {
 			},
 			},
 
 
 			http.StatusInternalServerError,
 			http.StatusInternalServerError,
-			`{"message":"Internal Server Error"}`,
+			`{"errorCode":300,"message":"Raft Internal Error","cause":"Internal Server Error","index":0}`,
 		},
 		},
 		{
 		{
 			// etcdserver.Server etcd error
 			// etcdserver.Server etcd error
@@ -1426,7 +1426,7 @@ func TestBadServeKeys(t *testing.T) {
 			},
 			},
 
 
 			http.StatusInternalServerError,
 			http.StatusInternalServerError,
-			`{"message":"Internal Server Error"}`,
+			`{"errorCode":300,"message":"Raft Internal Error","cause":"received response with no Event/Watcher!","index":0}`,
 		},
 		},
 	}
 	}
 	for i, tt := range testBadCases {
 	for i, tt := range testBadCases {