Start learning free

LESSON 26 OF 173 · BACKEND: YOUR FIRST API

One Way to Send Errors

Practice

Your shop sends errors from six places, and each one builds map[string]string{"error": ...} by hand. A client relies on every error having the same shape: it reads the message under the key "error". One typo in one place, like "eror", and the client loses that message.

The fix is a helper function: an ordinary function, never registered with app.HandleFunc, that writes the answer in one place. It isn't a route; the handlers call it. It takes w, the same http.ResponseWriter the handler got, so it can write the status and the body for the handler. A helper for success answers could look like this (not part of the shop):

func created(w http.ResponseWriter, item any) {
	writeJSON(w, 201, item)
}

app.HandleFunc("POST /notes", func(w http.ResponseWriter, r *http.Request) {
	var note map[string]string
	json.NewDecoder(r.Body).Decode(&note)
	notes = append(notes, note)
	created(w, note)
})

Right now the error lines are missing from the handlers, and a handler that ends without writing anything answers 200 with an empty body. Once every error goes through the helper, the answers are the same as before; only the code gets tidier. The requests and answers your code must give, in this order:

GET /products/9  →  404  {"error": "Product not found"}
POST /products  {"price": 5, "category": "kitchen"}
  →  400  {"error": "Name is required"}
POST /products  {"name": "Cup", "price": -1, "category": "kitchen"}
  →  400  {"error": "Price must be a whole number of 0 or more"}
DELETE /products/9  →  404  {"error": "Product not found"}
PUT /products/9  {"name": "Cup", "price": 5, "category": "kitchen"}
  →  404  {"error": "Product not found"}
PATCH /products/9  {"price": 5}  →  404  {"error": "Product not found"}
POST /products  {"name": "Cup", "price": 5, "category": "kitchen"}
  →  201  {"id": 5, "name": "Cup", "price": 5, "category": "kitchen"}
GET /products/5  →  200  {"id": 5, "name": "Cup", "price": 5, "category": "kitchen"}

Your task: write errorResponse(w, message, status), which writes the JSON body {"error": message} with the given status through writeJSON, and use it for every error answer in the shop: the 404 of the GET, DELETE, PUT and PATCH handlers for /products/{id}, and the two 400s of the POST /products handler.


Assignment
Follow the Coding Tutorial to write the errorResponse helper and send every error through it.


Hint
The helper goes below writeJSON, outside newApp. In the POST checks, the call goes above the return that is already there: the call writes the answer, and return stops the handler.


STEP 1 OF 8
    Ctrl + Enter to check