From 2c08026a2cba794c599ad2d9b4766b9183957523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Wieczorek?= Date: Sun, 31 Dec 2017 16:00:41 +0100 Subject: [PATCH] Add helpers for common tasks in action handlers This patch also changes internal server error message and action handlers tests to unify all error messages. --- errors.go | 8 ++++++++ handlers.go | 24 +++++++++++++++++++----- handlers_test.go | 2 +- 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 errors.go diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..393bafd --- /dev/null +++ b/errors.go @@ -0,0 +1,8 @@ +package main + +import "errors" + +var ( + // ErrRelayNotFound is returned when Relay is not found. + ErrRelayNotFound = errors.New("relay not found") +) diff --git a/handlers.go b/handlers.go index 705abc3..0f1e976 100644 --- a/handlers.go +++ b/handlers.go @@ -25,14 +25,28 @@ func RelayIndex(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { // RelayShow handles the relays show action (GET /relays/:id). func RelayShow(w http.ResponseWriter, r *http.Request, params httprouter.Params) { id := params.ByName("id") + relay, err := findRelay(id) + if err != nil { + writeError(w, http.StatusNotFound, err.Error()) + return + } + writeResponse(w, http.StatusOK, &JsonResponse{Data: relay}) +} + +// findRelay locates Relay with the given ID on the module. +func findRelay(id string) (*Relay, error) { relay, ok := module[id] if !ok { // No relay with the ID given in the URL has been found - apiError := &ApiError{Status: http.StatusNotFound, Title: "Relay not found"} - writeResponse(w, http.StatusNotFound, &JsonErrorResponse{Error: apiError}) - return + return nil, ErrRelayNotFound } - writeResponse(w, http.StatusOK, &JsonResponse{Data: relay}) + return relay, nil +} + +// writeError wraps writing API error response. +func writeError(w http.ResponseWriter, status int, title string) { + apiError := &ApiError{Status: status, Title: title} + writeResponse(w, status, &JsonErrorResponse{Error: apiError}) } // writeResponse writes standard JSON API response with status code. @@ -40,7 +54,7 @@ func writeResponse(w http.ResponseWriter, status int, response interface{}) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(status) if err := json.NewEncoder(w).Encode(response); err != nil { - apiError := &ApiError{Status: http.StatusInternalServerError, Title: "Internal server error"} + apiError := &ApiError{Status: http.StatusInternalServerError, Title: "internal server error"} writeResponse(w, http.StatusInternalServerError, apiError) } } diff --git a/handlers_test.go b/handlers_test.go index 8dac85c..0cc8be8 100644 --- a/handlers_test.go +++ b/handlers_test.go @@ -45,7 +45,7 @@ var _ = Describe("Main", func() { }) It("should return an error on show request for nonexistent relay", func() { - expected := "{\"error\":{\"status\":404,\"title\":\"Relay not found\"}}\n" + expected := "{\"error\":{\"status\":404,\"title\":\"relay not found\"}}\n" actual := call("GET", "/relays/I0", "/relays/:id", RelayShow) Expect(actual.Code).To(Equal(http.StatusNotFound)) Expect(actual.Body.String()).To(MatchJSON(expected))