mirror of
https://github.com/kataras/iris.git
synced 2025-12-17 09:57:01 +00:00
error handlers per party: log those routes too and all test cases paased
need cleanup though Former-commit-id: 6b0c18e38b58af2388015c7cf1af9cc43d7d35d3
This commit is contained in:
@@ -981,23 +981,11 @@ func (api *APIBuilder) Favicon(favPath string, requestPath ...string) *Route {
|
||||
func (api *APIBuilder) OnErrorCode(statusCode int, handlers ...context.Handler) {
|
||||
// TODO: think a stable way for that and document it so end-developers
|
||||
// not be suprised. Many feature requests in the past asked for that per-party error handlers.
|
||||
api.handle(statusCode, "", "/", handlers...)
|
||||
|
||||
if api.relativePath != "/" {
|
||||
api.handle(statusCode, "", "/{tail:path}", handlers...)
|
||||
}
|
||||
|
||||
api.handle(statusCode, "", "/", handlers...)
|
||||
|
||||
// if api.relativePath != "/" /* root is OK, no need to wildcard, see handler.go */ &&
|
||||
// !strings.HasSuffix(api.relativePath, "}") /* and not /users/{id:int} */ {
|
||||
// // We need to register the /users and the /users/{tail:path},
|
||||
// api.handle(statusCode, "", "/{tail:path}", handlers...)
|
||||
// }
|
||||
|
||||
// if strings.HasSuffix(api.relativePath, "/") {
|
||||
// api.handle(statusCode, "", "/", handlers...)
|
||||
// }
|
||||
|
||||
// api.handle(statusCode, "", "/{tail:path}", handlers...)
|
||||
}
|
||||
|
||||
// OnAnyErrorCode registers a handler which called when error status code written.
|
||||
@@ -1058,26 +1046,33 @@ func getCaller() (string, int) {
|
||||
wd, _ := os.Getwd()
|
||||
for {
|
||||
frame, more := frames.Next()
|
||||
file := frame.File
|
||||
file := filepath.ToSlash(frame.File)
|
||||
|
||||
if strings.Contains(file, "src/testing/testing.go") {
|
||||
if !strings.Contains(file, "_test.go") {
|
||||
if strings.Contains(file, "/kataras/iris") && !strings.Contains(file, "kataras/iris/_examples") && !strings.Contains(file, "iris-contrib/examples") {
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Contains(file, "go/src/runtime/") {
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.Contains(file, "/kataras/iris") ||
|
||||
strings.Contains(file, "_examples") ||
|
||||
strings.Contains(file, "examples") {
|
||||
if relFile, err := filepath.Rel(wd, file); err == nil {
|
||||
if !strings.HasPrefix(relFile, "..") {
|
||||
// Only if it's relative to this path, not parent.
|
||||
file = "./" + relFile
|
||||
}
|
||||
}
|
||||
|
||||
return file, frame.Line
|
||||
}
|
||||
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return "???", 0
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ func (h *routerHandler) Build(provider RoutesProvider) error {
|
||||
routes []*Route
|
||||
}
|
||||
|
||||
allMethods := append(AllMethods, MethodNone)
|
||||
allMethods := append(AllMethods, []string{MethodNone, ""}...)
|
||||
methodRoutes := make([]MethodRoutes, 0, len(allMethods))
|
||||
|
||||
for _, method := range allMethods {
|
||||
@@ -246,6 +246,9 @@ func (h *routerHandler) Build(provider RoutesProvider) error {
|
||||
fmt.Fprint(logger.Printer, ", ")
|
||||
}
|
||||
}
|
||||
if m.method == "" {
|
||||
m.method = "ERROR"
|
||||
}
|
||||
fmt.Fprintf(logger.Printer, "%d ", len(m.routes))
|
||||
pio.WriteRich(logger.Printer, m.method, traceMethodColor(m.method))
|
||||
}
|
||||
@@ -459,6 +462,16 @@ func (h *routerHandler) FireErrorCode(ctx context.Context) {
|
||||
}
|
||||
|
||||
if n != nil {
|
||||
// Note: handlers can contain macro filters here,
|
||||
// they are registered as error handlers, see macro/handler.go#42.
|
||||
|
||||
// fmt.Println("Error Handlers")
|
||||
// for _, h := range n.Handlers {
|
||||
|
||||
// f, l := context.HandlerFileLine(h)
|
||||
// fmt.Printf("%s: %s:%d\n", ctx.Path(), f, l)
|
||||
// }
|
||||
|
||||
// fire this http status code's error handlers chain.
|
||||
|
||||
// ctx.StopExecution() // not uncomment this, is here to remember why to.
|
||||
|
||||
@@ -386,7 +386,7 @@ func traceMethodColor(method string) int {
|
||||
return color
|
||||
}
|
||||
|
||||
return pio.Black
|
||||
return 131 // for error handlers, of "ERROR [%STATUSCODE]"
|
||||
}
|
||||
|
||||
// Trace prints some debug info about the Route to the "w".
|
||||
@@ -397,13 +397,18 @@ func traceMethodColor(method string) int {
|
||||
// * @second_handler ...
|
||||
// If route and handler line:number locations are equal then the second is ignored.
|
||||
func (r *Route) Trace(w io.Writer) {
|
||||
method := r.Method
|
||||
if method == "" {
|
||||
method = fmt.Sprintf("%d", r.StatusCode)
|
||||
}
|
||||
|
||||
// Color the method.
|
||||
color := traceMethodColor(r.Method)
|
||||
color := traceMethodColor(method)
|
||||
|
||||
// @method: @path
|
||||
// space := strings.Repeat(" ", len(http.MethodConnect)-len(r.Method))
|
||||
// s := fmt.Sprintf("%s: %s", pio.Rich(r.Method, color), path)
|
||||
pio.WriteRich(w, r.Method, color)
|
||||
// space := strings.Repeat(" ", len(http.MethodConnect)-len(method))
|
||||
// s := fmt.Sprintf("%s: %s", pio.Rich(method, color), path)
|
||||
pio.WriteRich(w, method, color)
|
||||
|
||||
path := r.Tmpl().Src
|
||||
if path == "" {
|
||||
@@ -415,7 +420,7 @@ func (r *Route) Trace(w io.Writer) {
|
||||
// (@description)
|
||||
description := r.Description
|
||||
if description == "" {
|
||||
if r.Method == MethodNone {
|
||||
if method == MethodNone {
|
||||
description = "offline"
|
||||
}
|
||||
|
||||
|
||||
@@ -89,27 +89,30 @@ func TestPartyOnErrorCode(t *testing.T) {
|
||||
|
||||
app.Get("/path", h)
|
||||
|
||||
h := func(ctx iris.Context) { ctx.WriteString(ctx.Path()) }
|
||||
usersResponse := "users: method allowed"
|
||||
|
||||
users := app.Party("/users")
|
||||
users.OnErrorCode(iris.StatusMethodNotAllowed, func(ctx iris.Context) {
|
||||
ctx.WriteString(usersResponse)
|
||||
})
|
||||
users.Get("/", h)
|
||||
write400 := func(ctx iris.Context) { ctx.StatusCode(iris.StatusBadRequest) }
|
||||
// test setting the error code from a handler.
|
||||
users.Get("/badrequest", func(ctx iris.Context) { ctx.StatusCode(iris.StatusBadRequest) })
|
||||
users.Get("/badrequest", write400)
|
||||
|
||||
usersuserResponse := "users:user: method allowed"
|
||||
user := users.Party("/{id:int}")
|
||||
user.OnErrorCode(iris.StatusMethodNotAllowed, func(ctx iris.Context) {
|
||||
ctx.WriteString(usersuserResponse)
|
||||
})
|
||||
// usersuserNotFoundResponse := "users:user: not found"
|
||||
// user.OnErrorCode(iris.StatusNotFound, func(ctx iris.Context) {
|
||||
// ctx.WriteString(usersuserNotFoundResponse)
|
||||
// })
|
||||
usersuserNotFoundResponse := "users:user: not found"
|
||||
user.OnErrorCode(iris.StatusNotFound, func(ctx iris.Context) {
|
||||
ctx.WriteString(usersuserNotFoundResponse)
|
||||
})
|
||||
user.Get("/", h)
|
||||
user.Get("/ab/badrequest", write400)
|
||||
|
||||
friends := users.Party("/friends")
|
||||
friends.Get("/{id:int}", h)
|
||||
|
||||
e := httptest.New(t, app)
|
||||
|
||||
@@ -125,10 +128,12 @@ func TestPartyOnErrorCode(t *testing.T) {
|
||||
|
||||
e.GET("/users/42").Expect().Status(iris.StatusOK).
|
||||
Body().Equal("/users/42")
|
||||
// e.GET("/users/ab").Expect().Status(iris.StatusNotFound).Body().Equal(usersuserNotFoundResponse)
|
||||
e.GET("/users/ab").Expect().Status(iris.StatusNotFound).Body().Equal(usersuserNotFoundResponse)
|
||||
// inherit the parent.
|
||||
e.GET("/users/42/friends/dsa").Expect().Status(iris.StatusNotFound).Body().Equal(usersuserNotFoundResponse)
|
||||
|
||||
// if not registered to the party, then the root is taking action.
|
||||
e.GET("/users/ab/cd").Expect().Status(iris.StatusNotFound).Body().Equal(globalNotFoundResponse)
|
||||
e.GET("/users/42/ab/badrequest").Expect().Status(iris.StatusBadRequest).Body().Equal(http.StatusText(iris.StatusBadRequest))
|
||||
|
||||
// if not registered to the party, and not in root, then just write the status text (fallback behavior)
|
||||
e.GET("/users/badrequest").Expect().Status(iris.StatusBadRequest).
|
||||
|
||||
@@ -41,8 +41,11 @@ func newSource(fn reflect.Value) Source {
|
||||
|
||||
wd, _ := os.Getwd()
|
||||
if relFile, err := filepath.Rel(wd, callerFileName); err == nil {
|
||||
if !strings.HasPrefix(relFile, "..") {
|
||||
// Only if it's relative to this path, not parent.
|
||||
callerFileName = "./" + relFile
|
||||
}
|
||||
}
|
||||
|
||||
return Source{
|
||||
File: callerFileName,
|
||||
|
||||
@@ -39,11 +39,17 @@ func MakeHandler(tmpl macro.Template) context.Handler {
|
||||
|
||||
return func(ctx context.Context) {
|
||||
if !filter(ctx) {
|
||||
if ctx.GetCurrentRoute().StatusErrorCode() == ctx.GetStatusCode() {
|
||||
ctx.Next()
|
||||
} else {
|
||||
ctx.StopExecution()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// if all passed, just continue.
|
||||
// if all passed or the next is the registered error handler to handle this status code,
|
||||
// just continue.
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user