Gehen die Fehlerbehandlung auf einer REST-API
Ich bin ganz neu gehen und bereitgestellt haben, eine kleine service mit einer API-endpoint.
Ich habe gehört/gelesen, die gehen nicht try/catch
so versuche ich herauszufinden, wie ich kann "catch" Probleme geschieht aus meiner service-Aufruf aus meiner API und stellen Sie sicher, dass die Ressource server nicht down gehen.
Mein code für mein API sieht wie folgt aus..
Ich habe eine routes.go
- Datei mit dem folgenden
package main
import (
"net/http"
"github.com/gorilla/mux"
)
type Route struct {
Name string
Method string
Pattern string
HandlerFunc http.HandlerFunc
}
type Routes []Route
func NewRouter() *mux.Router {
router := mux.NewRouter().StrictSlash(true)
for _, route := range routes {
router.
Methods(route.Method).
Path(route.Pattern).
Name(route.Name).
Handler(route.HandlerFunc)
}
return router
}
var routes = Routes{
Route{
"CustomerLocationCreate",
"POST",
"/tracking/customer",
CustomerLocationCreate,
},
}
Ich habe eine handlers.go
package main
import (
"encoding/json"
"net/http"
"io"
"io/ioutil"
)
//curl -H "Content-Type: application/json" -d '{"userId":"1234"}' http://localhost:8181/tracking/customer
func CustomerLocationCreate(w http.ResponseWriter, r *http.Request) {
var location CustomerLocation
body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))
if err != nil {
panic(err)
}
if err := r.Body.Close(); err != nil {
panic(err)
}
if err := json.Unmarshal(body, &location); err != nil {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(422) //unprocessable entity
if err := json.NewEncoder(w).Encode(err); err != nil {
panic(err)
}
}
c := RepoCreateCustomerLocation(location)
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusCreated)
if err := json.NewEncoder(w).Encode(c); err != nil {
panic(err)
}
HandleCustomerLocationChange(c);
}
und ich habe eine bus.go
hat die HandleCustomerLocationChange(...)
Funktion.
func HandleCustomerLocationChange(custLoc CustomerLocation) {
endpoint := og.Getenv("RABBIT_ENDPOINT")
conn, err := amqp.Dial("amqp://guest:guest@" + endpoint)
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close()
ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
defer ch.Close()
topic := "locationChange"
err = ch.ExchangeDeclare(
topic, //name
"topic", //type
true, //durable
false, //auto-deleted
false, //internal
false, //no-wait
nil, //arguments
)
failOnError(err, "Failed to declare an exchange")
//Create JSON from the instance data.
body, _ := json.Marshal(custLoc)
//Convert bytes to string.
err = ch.Publish(
topic, //exchange
"", //routing key
false, //mandatory
false, //immediate
amqp.Publishing{
ContentType: "text/plain",
Body: body,
})
failOnError(err, "Failed to publish a message")
log.Printf(" [x] Sent %s", body)
}
Meine Frage ist wie sollte ich ändern, sowohl die HandleCustomerLocationChange(...) function and if necessary
CustomerLocationChange(..)` handler behandeln Fehler richtig so, dass wenn ein Fehler Auftritt, meine gesamte API nicht nach unten gehen?
- Rufen Sie nicht in Panik. Verwenden
http.Error
zu schreiben eine Fehlermeldung als Antwort, oder schreiben Sie Ihre eigenen generiert eine JSON-error-response.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gehen, schlägt einen anderen Ansatz, Fehler sind nicht außergewöhnlich, Sie sind normale Ereignisse, nur weniger Häufig.
Nehmen ein Beispiel aus dem obigen code:
Hier, Panik (ohne Wiederherstellung) beendet den Prozess, Herunterfahren des web-Servers. Scheint eine übermäßig starke Reaktion auf nicht vollständig Lesen einer Anfrage.
Was möchten Sie tun? Es kann angebracht sein, zu sagen, den client, der die Anfrage gestellt:
Möchten Sie vielleicht, um wieder eine json-kodierte Antwort, oder geben Sie eine Allgemeine Nachricht an den client vermeiden Sie es, zu viel, und melden Sie die spezifischen Fehlerdetails.
Für die Allgemeinen Funktionen der idiomatischen, um wieder den Fehler wie das Letzte return-parameter. In dem spezifischen Beispiel, das Sie erwähnt:
Stattdessen prüfen, ob die Verbindung fehlgeschlagen ist, und wieder den Fehler an den Aufrufer. Griff es in die aufrufende Funktion, oder fügen Sie Daten und übertragen Sie es oben auf dem Aufruf-stack.
Vermehrung der Fehler auf diese Weise bietet Sie eine knappe Erklärung der Ursache, wie die 5 warums Technik, zB:
"nicht-update-client-Position: hat keine Verbindung zu rabbitmq: network address 1.2.3 nicht erreichbar"
Anderen Konvention ist es, sich mit Fehlern Erster und Rückkehr zu früh. Dies hilft zu reduzieren verschachteln.
Siehe auch die vielen Fehler Umgang mit Ressourcen, wie Fehlerbehandlung in einer web-Anwendung, Gehen Sie durch Beispiel, Fehlerbehandlung und Gehen, Fehler sind die Werte, die und Defer, Panic & Wiederherstellen. Der source-code der Fehler Paket ist interessant, wie Russ Cox ' s Kommentar zur Fehlerbehandlung, und Nathan Youngman s Irren ist Menschlich.
Interessant ist auch Upspin Konzept von einer operativen trace, anstatt einen stack-trace.