net/http.Error în Go

Error trimite un răspuns de eroare cu cod și mesaj text; NotFound trimite 404; StatusText dă textul unui cod (404 → Not Found).

Sintaxă
func Error(w ResponseWriter, error string, code int)
func NotFound(w ResponseWriter, r *Request)
func StatusText(code int) string

Ce face net/http.Error

http.Error(w, "mesaj", 400) setează Content-Type: text/plain; charset=utf-8 și X-Content-Type-Options: nosniff, trimite codul și scrie mesajul urmat de linie nouă. Nu oprește handler-ul: scrie return imediat după.

http.NotFound(w, r) este scurtătura pentru http.Error(w, "404 page not found", 404). http.StatusText(cod) returnează textul standard al unui cod ("Not Found", "Internal Server Error") sau "" pentru coduri necunoscute.

În loc de numere, folosește constantele pachetului: http.StatusBadRequest (400), http.StatusUnauthorized (401), http.StatusForbidden (403), http.StatusNotFound (404), http.StatusInternalServerError (500).

Parametri

Parametru Descriere
w Răspunsul.
error Mesajul pentru client (text simplu).
code Codul de stare HTTP.

Ce returnează

Error și NotFound: nimic. StatusText: textul codului.

Exemple

Exemplul 1: Validarea unei cereri

package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"
)

var produse = map[string]float64{"cafea": 32.5, "ceai": 14}

func pret(w http.ResponseWriter, r *http.Request) {
	nume := r.URL.Query().Get("produs")
	if nume == "" {
		http.Error(w, "lipsește parametrul produs", http.StatusBadRequest)
		return
	}
	p, ok := produse[nume]
	if !ok {
		http.NotFound(w, r)
		return
	}
	fmt.Fprintf(w, "%s: %.2f lei", nume, p)
}

func main() {
	for _, url := range []string{"/pret?produs=cafea", "/pret", "/pret?produs=zahar"} {
		rec := httptest.NewRecorder()
		pret(rec, httptest.NewRequest("GET", url, nil))
		fmt.Printf("%-22s %d %-11s %s\n", url, rec.Code, http.StatusText(rec.Code), strings.TrimSpace(rec.Body.String()))
	}
	rec := httptest.NewRecorder()
	pret(rec, httptest.NewRequest("GET", "/pret", nil))
	fmt.Println("Content-Type:", rec.Header().Get("Content-Type"))
}

Rezultat

/pret?produs=cafea     200 OK          cafea: 32.50 lei
/pret                  400 Bad Request lipsește parametrul produs
/pret?produs=zahar     404 Not Found   404 page not found
Content-Type: text/plain; charset=utf-8

Exemplul 2: Textul codurilor de stare

package main

import (
	"fmt"
	"net/http"
)

func main() {
	for _, cod := range []int{200, 201, 301, 400, 401, 403, 404, 418, 500, 503, 999} {
		fmt.Printf("%d %q\n", cod, http.StatusText(cod))
	}
}

Rezultat

200 "OK"
201 "Created"
301 "Moved Permanently"
400 "Bad Request"
401 "Unauthorized"
403 "Forbidden"
404 "Not Found"
418 "I'm a teapot"
500 "Internal Server Error"
503 "Service Unavailable"
999 ""

Greșeli frecvente

  • Uiți return după http.Error: codul de după rulează și scrie în continuare în răspuns.
  • Trimiți clientului mesajul intern al erorii (http.Error(w, err.Error(), 500)), care poate conține căi, interogări SQL sau parole. Jurnalizează eroarea și trimite un mesaj general.
  • Folosești http.Error pentru un API JSON: răspunsul este text simplu. Pentru JSON setează antetul, codul și scrie JSON-ul tu.

Comenzi înrudite

  • net/http.ResponseWriter: Interfața prin care handler-ul construiește răspunsul: antete (Header), cod de stare (WriteHeader) și corp (Write).
  • net/http.Redirect: Trimite clientul la altă adresă (antetul Location) cu un cod 3xx: 301 mutat definitiv, 302/303 temporar.
  • net/http.Handler: Interfața oricărui obiect care răspunde la cereri HTTP (metoda ServeHTTP); HandlerFunc transformă o funcție în Handler.