|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- package handlers
-
- import (
- "fmt"
- "net/http"
- )
-
- // Augmented response writer to hold the panic data (can be anything, not necessarily an error
- // interface).
- type errResponseWriter struct {
- http.ResponseWriter
- perr interface{}
- }
-
- // Implement the WrapWriter interface.
- func (this *errResponseWriter) WrappedWriter() http.ResponseWriter {
- return this.ResponseWriter
- }
-
- // PanicHandlerFunc is the same as PanicHandler, it is just a convenience
- // signature that accepts a func(http.ResponseWriter, *http.Request) instead of
- // a http.Handler interface. It saves the boilerplate http.HandlerFunc() cast.
- func PanicHandlerFunc(h http.HandlerFunc, errH http.HandlerFunc) http.HandlerFunc {
- return PanicHandler(h, errH)
- }
-
- // Calls the wrapped handler and on panic calls the specified error handler. If the error handler is nil,
- // responds with a 500 error message.
- func PanicHandler(h http.Handler, errH http.Handler) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- defer func() {
- if err := recover(); err != nil {
- if errH != nil {
- ew := &errResponseWriter{w, err}
- errH.ServeHTTP(ew, r)
- } else {
- http.Error(w, fmt.Sprintf("%s", err), http.StatusInternalServerError)
- }
- }
- }()
-
- // Call the protected handler
- h.ServeHTTP(w, r)
- }
- }
-
- // Helper function to retrieve the panic error, if any.
- func GetPanicError(w http.ResponseWriter) (interface{}, bool) {
- er, ok := GetResponseWriter(w, func(tst http.ResponseWriter) bool {
- _, ok := tst.(*errResponseWriter)
- return ok
- })
- if ok {
- return er.(*errResponseWriter).perr, true
- }
- return nil, false
- }
|