Permalink
Browse files

Add a FINALLY plugin & interception time.

Only cast result to (Result) if it is non-nil.
  • Loading branch information...
1 parent 14359ff commit d34c8eea6013292cfbf9173c357c6fc9f0dd8f35 @robfig committed Nov 24, 2012
Showing with 29 additions and 15 deletions.
  1. +12 −12 controller.go
  2. +6 −1 intercept.go
  3. +11 −2 plugin.go
View
@@ -64,6 +64,8 @@ func (c *Controller) Invoke(appControllerPtr reflect.Value, method reflect.Value
if err := recover(); err != nil {
handleInvocationPanic(c, err)
}
+
+ plugins.Finally(c)
}()
// Clean up from the request.
@@ -86,20 +88,18 @@ func (c *Controller) Invoke(appControllerPtr reflect.Value, method reflect.Value
// Run the plugins.
plugins.BeforeRequest(c)
- if c.Result != nil {
- c.Result.Apply(c.Request, c.Response)
- return
- }
-
- // Invoke the action.
- resultValue := method.Call(methodArgs)[0]
- c.Result = resultValue.Interface().(Result)
-
- plugins.AfterRequest(c)
- // if resultValue.Kind() == reflect.Interface && resultValue.IsNil() {
if c.Result == nil {
- return
+ // Invoke the action.
+ resultValue := method.Call(methodArgs)[0]
+ if resultValue.Kind() == reflect.Interface && !resultValue.IsNil() {
+ c.Result = resultValue.Interface().(Result)
+ }
+
+ plugins.AfterRequest(c)
+ if c.Result == nil {
+ return
+ }
}
// Apply the result, which generally results in the ResponseWriter getting written.
View
@@ -42,6 +42,7 @@ const (
BEFORE InterceptTime = iota
AFTER
PANIC
+ FINALLY
)
type InterceptTarget int
@@ -100,6 +101,10 @@ func (p InterceptorPlugin) OnException(c *Controller, err interface{}) {
invokeInterceptors(PANIC, c)
}
+func (p InterceptorPlugin) Finally(c *Controller) {
+ invokeInterceptors(FINALLY, c)
+}
+
func invokeInterceptors(when InterceptTime, c *Controller) {
appControllerPtr := reflect.ValueOf(c.AppController)
result := func() Result {
@@ -117,7 +122,7 @@ func invokeInterceptors(when InterceptTime, c *Controller) {
}()
if result != nil {
- appControllerPtr.Elem().FieldByName("Result").Set(reflect.ValueOf(result))
+ c.Result = result
}
}
View
@@ -8,10 +8,12 @@ type Plugin interface {
OnRoutesLoaded(router *Router)
// Called before every request.
BeforeRequest(c *Controller)
- // Called after every request (except on panics).
+ // Called after every non-panicking request, before the Result has been applied.
AfterRequest(c *Controller)
- // Called when a panic exits an action, with the recovered value.
+ // Called when a panic exits an action, with the recovered error value.
OnException(c *Controller, err interface{})
+ // Called after every request (panic or not), after the Result has been applied.
+ Finally(c *Controller)
}
// It provides default (empty) implementations for all the required methods.
@@ -22,6 +24,7 @@ func (p EmptyPlugin) OnRoutesLoaded(router *Router) {}
func (p EmptyPlugin) BeforeRequest(c *Controller) {}
func (p EmptyPlugin) AfterRequest(c *Controller) {}
func (p EmptyPlugin) OnException(c *Controller, err interface{}) {}
+func (p EmptyPlugin) Finally(c *Controller) {}
type PluginCollection []Plugin
@@ -60,3 +63,9 @@ func (plugins PluginCollection) OnException(c *Controller, err interface{}) {
p.OnException(c, err)
}
}
+
+func (plugins PluginCollection) Finally(c *Controller) {
+ for _, p := range plugins {
+ p.Finally(c)
+ }
+}

0 comments on commit d34c8ee

Please sign in to comment.