woodpecker/server/handler/error.go
2014-06-04 14:25:38 -07:00

65 lines
2.3 KiB
Go

package handler
import (
"log"
"net/http"
)
// badRequest is handled by setting the status code in the reply to StatusBadRequest.
type badRequest struct{ error }
// notFound is handled by setting the status code in the reply to StatusNotFound.
type notFound struct{ error }
// notAuthorized is handled by setting the status code in the reply to StatusNotAuthorized.
type notAuthorized struct{ error }
// notImplemented is handled by setting the status code in the reply to StatusNotImplemented.
type notImplemented struct{ error }
// forbidden is handled by setting the status code in the reply to StatusForbidden.
type forbidden struct{ error }
// internalServerError is handled by setting the status code in the reply to StatusInternalServerError.
type internalServerError struct{ error }
// errorHandler wraps a function returning an error by handling the error and returning a http.Handler.
// If the error is of the one of the types defined above, it is handled as described for every type.
// If the error is of another type, it is considered as an internal error and its message is logged.
func errorHandler(f func(w http.ResponseWriter, r *http.Request) error) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// standard header variables that should be set, for good measure.
w.Header().Add("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate")
w.Header().Add("X-Frame-Options", "DENY")
w.Header().Add("X-Content-Type-Options", "nosniff")
w.Header().Add("X-XSS-Protection", "1; mode=block")
// serve the request
err := f(w, r)
if err == nil {
return
}
// log the url for debugging purposes
log.Println(r.Method, r.URL.Path)
switch err.(type) {
case badRequest:
log.Println(err)
http.Error(w, err.Error(), http.StatusBadRequest)
case notFound:
http.Error(w, "Not Found", http.StatusNotFound)
case notAuthorized:
http.Error(w, "Not Authorized", http.StatusUnauthorized)
case notImplemented:
http.Error(w, "Not Implemented", http.StatusForbidden)
case forbidden:
http.Error(w, "Forbidden", http.StatusForbidden)
case internalServerError:
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
default:
log.Println(err)
http.Error(w, "oops", http.StatusInternalServerError)
}
}
}