Skip to content

Commit

Permalink
Added Recover functions
Browse files Browse the repository at this point in the history
  • Loading branch information
pikanezi committed Jan 30, 2016
1 parent 5c9e018 commit 8538431
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 0 deletions.
4 changes: 4 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import (
// The HandlerFunction type is an adapter to allow the use of ordinary functions as route handlers.
type HandlerFunction func(*RequestContext) error

// RecovererFunction type is a function containing the RequestContext of the request that panicked
// and the value recovered.
type RecovererFunction func(*RequestContext, interface{})

// HandlerErrorFunction type is the type used by error interceptors.
type HandlerErrorFunction func(*RequestContext, error) error

Expand Down
7 changes: 7 additions & 0 deletions pi.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ func wrapHandler(handler HandlerFunction, routeURL string, parentRoutes ...*Rout
copy(closureParentRoutes, parentRoutes)
return func(w http.ResponseWriter, r *http.Request) {
context := newRequestContext(w, r, routeURL)
defer func() {
if recoveredValue := recover(); recoveredValue != nil {
for _, parentRoute := range closureParentRoutes {
parentRoute.Interceptors.runRecovererInterceptors(context, recoveredValue)
}
}
}()
errorInterceptors := func(c *RequestContext, err error) {
errorsHandled := false
for _, parentRoute := range closureParentRoutes {
Expand Down
13 changes: 13 additions & 0 deletions requestInterceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type interceptors struct {
Before []HandlerFunction
After []HandlerFunction
AfterAsync []HandlerFunction
Recoverers []RecovererFunction
Error []HandlerErrorFunction
}

Expand All @@ -28,6 +29,11 @@ func (i *interceptors) addAfterAsync(handler HandlerFunction) {
i.AfterAsync = append(i.AfterAsync, handler)
}

// addRecoverer appends a Recoverer interceptor.
func (i *interceptors) addRecoverer(recoverer RecovererFunction) {
i.Recoverers = append(i.Recoverers, recoverer)
}

// addError appends an Error interceptor.
func (i *interceptors) addError(handler HandlerErrorFunction) {
i.Error = append(i.Error, handler)
Expand Down Expand Up @@ -60,6 +66,13 @@ func (i *interceptors) runAfterAsyncInterceptors(c *RequestContext) {
}
}

// runRecovererInterceptors runs all the Recoverer interceptors.
func (i *interceptors) runRecovererInterceptors(c *RequestContext, recoverValue interface{}) {
for _, r := range i.Recoverers {
r(c, recoverValue)
}
}

// runAfterInterceptors runs all the Error interceptors, ignoring if an error is thrown.
func (i *interceptors) runErrorInterceptors(c *RequestContext, err error) (returnError error) {
for _, e := range i.Error {
Expand Down
7 changes: 7 additions & 0 deletions route.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ func (r *Route) AfterAsync(handlers ...HandlerFunction) *Route {
return r
}

func (r *Route) Recover(recoverers ...RecovererFunction) *Route {
for _, rr := range recoverers {
r.Interceptors.addRecoverer(rr)
}
return r
}

// Error registers an interceptor to be called when an error occurs in the request handler or in any Before interceptor.
func (r *Route) Error(handlers ...HandlerErrorFunction) *Route {
for _, handler := range handlers {
Expand Down

0 comments on commit 8538431

Please sign in to comment.