1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-17 18:07:01 +00:00

HandleHTTPError MVC Method as requested at #1595. Read HISTORY.md

example at: https://github.com/kataras/iris/tree/master/_examples/mvc/error-handler-http
This commit is contained in:
Gerasimos (Makis) Maropoulos
2020-08-22 08:04:22 +03:00
parent a018ba9b0a
commit 8e049d77c9
15 changed files with 186 additions and 16 deletions

View File

@@ -135,8 +135,14 @@ func newControllerActivator(app *Application, controller interface{}) *Controlle
return c
}
// It's a dynamic method, can be exist or not, it can accept input arguments
// and can write through output values like any other dev-designed method.
// See 'parseHTTPErrorMethod'.
// Example at: _examples/mvc/error-handler-http
const handleHTTPErrorMethodName = "HandleHTTPError"
func whatReservedMethods(typ reflect.Type) map[string][]*router.Route {
methods := []string{"BeforeActivation", "AfterActivation"}
methods := []string{"BeforeActivation", "AfterActivation", handleHTTPErrorMethodName}
// BeforeActivatior/AfterActivation are not routes but they are
// reserved names*
if isBaseController(typ) {
@@ -287,9 +293,16 @@ func (c *ControllerActivator) activate() {
return
}
c.parseHTTPErrorHandler()
c.parseMethods()
}
func (c *ControllerActivator) parseHTTPErrorHandler() {
if m, ok := c.Type.MethodByName(handleHTTPErrorMethodName); ok {
c.handleHTTPError(m.Name)
}
}
// register all available, exported methods to handlers if possible.
func (c *ControllerActivator) parseMethods() {
n := c.Type.NumMethod()
@@ -334,6 +347,40 @@ func (c *ControllerActivator) Handle(method, path, funcName string, middleware .
return routes[0]
}
// handleHTTPError is called when a controller's method
// with the "HandleHTTPError" is found. That method
// can accept dependencies like the rest but if it's not called manually
// then any dynamic dependencies depending on succesful requests
// may fail - this is end-developer's job;
// to register the correct dependencies or not do it all on that method.
//
// Note that if more than one controller in the same Party
// tries to register an http error handler then the
// overlap route rule should be used and a dependency
// on the controller (or method) level that will select
// between the two should exist (see mvc/authenticated-controller example).
func (c *ControllerActivator) handleHTTPError(funcName string) *router.Route {
handler := c.handlerOf("/", funcName)
routes := c.app.Router.OnAnyErrorCode(handler)
if len(routes) == 0 {
err := fmt.Errorf("MVC: unable to register an HTTP error code handler for '%s.%s'", c.fullName, funcName)
c.addErr(err)
return nil
}
for _, r := range routes {
r.Description = "controller"
r.MainHandlerName = fmt.Sprintf("%s.%s", c.fullName, funcName)
if m, ok := c.Type.MethodByName(funcName); ok {
r.SourceFileName, r.SourceLineNumber = context.HandlerFileLineRel(m.Func)
}
}
c.routes[funcName] = routes
return routes[0]
}
// HandleMany like `Handle` but can register more than one path and HTTP method routes
// separated by whitespace on the same controller's method.
// Keep note that if the controller's method input arguments are path parameters dependencies