Skip to content

Commit

Permalink
Merge pull request #20 from ferry-go/feature/core/added-custom-error-…
Browse files Browse the repository at this point in the history
…handler

added custom error handler
  • Loading branch information
ferry-go authored Jul 15, 2020
2 parents 9df571d + 29088c5 commit b1026f6
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 23 deletions.
7 changes: 7 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ func main() {

app := ferry.InitServer(&config)

app.HandleNotFound(func(ctx *ferry.Ctx) error {
return ctx.Json(http.StatusNotFound, "check url idiot")
})
app.HandleErrors(func(ctx *ferry.Ctx, err error) error {
return ctx.Send(http.StatusInternalServerError, err.Error())
})

// compression middleware
app.Use(middleware.Compress())

Expand Down
8 changes: 4 additions & 4 deletions middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ func appLevelMiddleware(ctx *Ctx, ferry *Ferry) {
if ctx.appMiddlewareIndex != len(ferry.middleware) {
handler := ferry.middleware[ctx.appMiddlewareIndex]
if err := handler(ctx); err != nil {
handlerRouterError(err, ctx)
handlerRouterError(err, ctx, ferry)
}
} else {
// handling request route
Expand All @@ -22,7 +22,7 @@ func appLevelMiddleware(ctx *Ctx, ferry *Ferry) {
handler := ferry.middleware[ctx.appMiddlewareIndex]
ctx.Next = next
if err := handler(ctx); err != nil {
handlerRouterError(err, ctx)
handlerRouterError(err, ctx, ferry)
}
} else {
handleRouting(ferry, ctx)
Expand All @@ -45,7 +45,7 @@ func groupLevelMiddleware(ctx *Ctx, ferry *Ferry, routers []router) {
if ctx.groupMiddlewareIndex != len(groupMiddlewares) {
handler := groupMiddlewares[ctx.groupMiddlewareIndex]
if err := handler(ctx); err != nil {
handlerRouterError(err, ctx)
handlerRouterError(err, ctx, ferry)
}
}
return nil
Expand All @@ -54,7 +54,7 @@ func groupLevelMiddleware(ctx *Ctx, ferry *Ferry, routers []router) {
ctx.Next = next
handler := groupMiddlewares[ctx.groupMiddlewareIndex]
if err := handler(ctx); err != nil {
handlerRouterError(err, ctx)
handlerRouterError(err, ctx, ferry)
}
}
}
Expand Down
34 changes: 22 additions & 12 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import (
// Middleware/Route Handler
type handler func(ctx *Ctx) error

// error handler
type errHandler func(ctx *Ctx, err error) error

type router struct {
routerPath string
regexPath string
Expand All @@ -24,10 +27,10 @@ type group struct {
}

var (
get = "GET"
post = "POST"
put = "PUT"
delete = "DELETE"
GET = http.MethodGet
POST = http.MethodPost
PUT = http.MethodPut
DELETE = http.MethodDelete
)

var routerRegexReplace = "[a-zA-Z0-9_-]*"
Expand All @@ -44,22 +47,22 @@ func (g *group) addRoute(method, path string, h handler) {

// Get method of ferry
func (g *group) Get(path string, h handler) {
g.addRoute(get, path, h)
g.addRoute(GET, path, h)
}

// Post method of ferry
func (g *group) Post(path string, h handler) {
g.addRoute(post, path, h)
g.addRoute(POST, path, h)
}

// Put method of ferry
func (g *group) Put(path string, h handler) {
g.addRoute(put, path, h)
g.addRoute(PUT, path, h)
}

// Delete method of ferry
func (g *group) Delete(path string, h handler) {
g.addRoute(delete, path, h)
g.addRoute(DELETE, path, h)
}

func (g *group) Use(h handler) {
Expand All @@ -79,21 +82,28 @@ func (g *group) Group(path string) *group {
func handle404(ferry *Ferry, ctx *Ctx) {
if ferry.urlNotFoundHandler != nil {
if err := ferry.urlNotFoundHandler(ctx); err != nil {
handlerRouterError(err, ctx)
handlerRouterError(err, ctx, ferry)
}
return
}
ctx.RequestCtx.Response.SetStatusCode(http.StatusNotFound)
ctx.RequestCtx.Response.SetBody([]byte("Not Found, Check URL"))
}

func handlerRouterError(err error, ctx *Ctx) {
func handlerRouterError(err error, ctx *Ctx, ferry *Ferry) {
if ferry.errorHandler != nil {
if handlerError := ferry.errorHandler(ctx, err); handlerError != nil {
ctx.RequestCtx.Response.SetStatusCode(http.StatusInternalServerError)
ctx.RequestCtx.Response.SetBody([]byte(handlerError.Error()))
}
return
}
ctx.RequestCtx.Response.SetStatusCode(http.StatusInternalServerError)
ctx.RequestCtx.Response.SetBody([]byte(err.Error()))
}

func handleRouting(ferry *Ferry, ctx *Ctx) {
// first get handler by method
// first GET handler by method
routesByMethod := ferry.routerMap[string(ctx.RequestCtx.Method())]
if routesByMethod != nil {
groupLevelMiddleware(ctx, ferry, routesByMethod)
Expand Down Expand Up @@ -139,7 +149,7 @@ func handleRouter(ctx *Ctx, ferry *Ferry, routers []router) {
ctx.routerPath = route.routerPath
ctx.queryPath = query.String()
if err := route.handler(ctx); err != nil {
handlerRouterError(err, ctx)
handlerRouterError(err, ctx, ferry)
}
return
}
Expand Down
21 changes: 16 additions & 5 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Ferry struct {
middleware []handler
groupMiddlewareMap map[string][]handler
urlNotFoundHandler handler
errorHandler errHandler
}

// Init server
Expand All @@ -42,6 +43,10 @@ func (ferry *Ferry) Listen(host string) error {
server := &fasthttp.Server{
NoDefaultServerHeader: true,
Handler: handler,
ErrorHandler: func(r *fasthttp.RequestCtx, err error) {
ctx := getRouterContext(r, ferry)
_ = ferry.errorHandler(ctx, err)
},
}
return server.ListenAndServe(host)
}
Expand All @@ -62,22 +67,22 @@ func (ferry *Ferry) Use(h handler) {

// Get method of ferry
func (ferry *Ferry) Get(path string, h handler) {
ferry.addRoute(get, path, h)
ferry.addRoute(GET, path, h)
}

// Post method of ferry
func (ferry *Ferry) Post(path string, h handler) {
ferry.addRoute(post, path, h)
ferry.addRoute(POST, path, h)
}

// Put method of ferry
func (ferry *Ferry) Put(path string, h handler) {
ferry.addRoute(put, path, h)
ferry.addRoute(PUT, path, h)
}

// Delete method of ferry
func (ferry *Ferry) Delete(path string, h handler) {
ferry.addRoute(delete, path, h)
ferry.addRoute(DELETE, path, h)
}

// Group method
Expand All @@ -88,11 +93,16 @@ func (ferry *Ferry) Group(path string) *group {
}
}

// custom 404 handler
// HandleNotFound custom 404 handler
func (ferry *Ferry) HandleNotFound(h handler) {
ferry.urlNotFoundHandler = h
}

// HandleErrors Handling errors at application level
func (ferry *Ferry) HandleErrors(h errHandler) {
ferry.errorHandler = h
}

// Serving
func (ferry *Ferry) serveFile(path, filePath, contentType string) {
ferry.Get(path, func(ctx *Ctx) error {
Expand All @@ -101,6 +111,7 @@ func (ferry *Ferry) serveFile(path, filePath, contentType string) {
})
}

// ServerDir files as routes
func (ferry *Ferry) ServerDir(path, dir string) {
var paths []string
if err := getAllPaths(dir, &paths); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (suite *ServerSuite) TestGetMethod() {
suite.Ferry.Get(path, func(ctx *Ctx) error {
return ctx.Send(http.StatusOK, "hey")
})
h := suite.Ferry.routerMap[get]
h := suite.Ferry.routerMap[GET]
if assert.NotNil(suite.T(), h) {
assert.Equal(suite.T(), h[0].routerPath, path, "router path should match")
regexPath := findAndReplace(path)
Expand All @@ -39,7 +39,7 @@ func (suite *ServerSuite) TestGetMethodResponse() {
suite.Ferry.Get(path, func(ctx *Ctx) error {
return ctx.Send(http.StatusOK, response)
})
r, err := http.NewRequest(get, "http://test"+path, nil)
r, err := http.NewRequest(GET, "http://test"+path, nil)
if assert.Nil(suite.T(), err) {
res, err := testServer(r, suite.Ferry)
if assert.Nil(suite.T(), err) {
Expand Down

0 comments on commit b1026f6

Please sign in to comment.