-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
61b89f2
commit 4f9921e
Showing
8 changed files
with
294 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"time" | ||
|
||
"github.com/studiolambda/akumu" | ||
"github.com/studiolambda/akumu/middleware" | ||
) | ||
|
||
type User struct { | ||
|
@@ -19,6 +21,51 @@ func user(request *http.Request) error { | |
JSON(User{Name: "Erik C. Forés", Email: "[email protected]"}) | ||
} | ||
|
||
func fails(request *http.Request) error { | ||
return errors.New("something went wrong") | ||
} | ||
|
||
func fails2(request *http.Request) error { | ||
return akumu. | ||
Response(http.StatusNotFound). | ||
Failed(errors.New("something went wrong")) | ||
} | ||
|
||
func fails3(request *http.Request) error { | ||
return akumu.Failed(akumu.Problem{ | ||
Type: "http://example.com/problems/not-found", | ||
Title: http.StatusText(http.StatusNotFound), | ||
Detail: "The requested resource could not be found.", | ||
Status: http.StatusNotFound, | ||
Instance: request.URL.String(), | ||
}) | ||
} | ||
|
||
func fails4(request *http.Request) error { | ||
return akumu.Response(http.StatusUnauthorized). | ||
Failed(akumu.Problem{ | ||
Type: "http://example.com/problems/not-found", | ||
Title: http.StatusText(http.StatusNotFound), | ||
Detail: "The requested resource could not be found.", | ||
Status: http.StatusNotFound, | ||
Instance: request.URL.String(), | ||
}) | ||
} | ||
|
||
func fails5(request *http.Request) error { | ||
return akumu.Response(http.StatusNotFound). | ||
Failed(akumu.Problem{ | ||
Type: "http://example.com/problems/not-found", | ||
Title: "page not found", | ||
Detail: "the requested resource could not be found.", | ||
Instance: request.URL.String(), | ||
}) | ||
} | ||
|
||
func panicable(request *http.Request) error { | ||
panic("something went wrong") | ||
} | ||
|
||
func sse(request *http.Request) error { | ||
messages := make(chan []byte) | ||
|
||
|
@@ -39,12 +86,18 @@ func sse(request *http.Request) error { | |
func main() { | ||
router := http.NewServeMux() | ||
|
||
router.HandleFunc("GET /", akumu.Handle(user)) | ||
router.HandleFunc("GET /sse", akumu.Handle(sse)) | ||
router.Handle("GET /", akumu.Handler(user)) | ||
router.Handle("GET /sse", akumu.Handler(sse)) | ||
router.Handle("GET /fails", akumu.Handler(fails)) | ||
router.Handle("GET /fails2", akumu.Handler(fails2)) | ||
router.Handle("GET /fails3", akumu.Handler(fails3)) | ||
router.Handle("GET /fails4", akumu.Handler(fails4)) | ||
router.Handle("GET /fails5", akumu.Handler(fails5)) | ||
router.Handle("GET /panic", akumu.Handler(panicable)) | ||
|
||
server := http.Server{ | ||
Addr: ":8080", | ||
Handler: router, | ||
Handler: middleware.Recover(router), | ||
} | ||
|
||
fmt.Println("Server is running on: ", server.Addr) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package middleware | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/studiolambda/akumu" | ||
) | ||
|
||
func Recover(handler http.Handler) http.Handler { | ||
return RecoverWith(handler, func(value any) error { | ||
switch err := (value).(type) { | ||
case error: | ||
return err | ||
case string: | ||
return errors.New(err) | ||
case fmt.Stringer: | ||
return errors.New(err.String()) | ||
} | ||
|
||
return errors.New("an unexpected error occurred") | ||
}) | ||
} | ||
|
||
func RecoverWith(handler http.Handler, handle func(value any) error) http.Handler { | ||
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { | ||
defer func() { | ||
if err := recover(); err != nil { | ||
akumu.HandleError(writer, request, handle(err), http.StatusInternalServerError) | ||
} | ||
}() | ||
|
||
handler.ServeHTTP(writer, request) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// This package implements the Problem Details for HTTP APIs (RFC 7807) specification. | ||
package akumu | ||
|
||
// Problem represents a problem details for HTTP APIs. | ||
// See https://tools.ietf.org/html/rfc7807 for more information. | ||
type Problem struct { | ||
Type string `json:"type"` | ||
Title string `json:"title"` | ||
Detail string `json:"detail"` | ||
Status int `json:"status"` | ||
Instance string `json:"instance"` | ||
} | ||
|
||
func (problem Problem) Error() string { | ||
return problem.Title | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package akumu_test | ||
|
||
import ( | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/studiolambda/akumu" | ||
) | ||
|
||
func problemHandler(request *http.Request) error { | ||
return akumu.Failed(akumu.Problem{ | ||
Type: "http://example.com/problems/not-found", | ||
Title: http.StatusText(http.StatusNotFound), | ||
Detail: "The requested resource could not be found.", | ||
Status: http.StatusNotFound, | ||
Instance: request.URL.String(), | ||
}) | ||
} | ||
|
||
func TestProblemHandler(t *testing.T) { | ||
request, err := http.NewRequest("GET", "/", nil) | ||
|
||
if err != nil { | ||
t.Fatalf("unable to create request: %s", err) | ||
} | ||
|
||
response := akumu.Record(problemHandler, request) | ||
|
||
if response.Code != http.StatusNotFound { | ||
t.Fatalf("unexpected status code: %d", response.Code) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package akumu | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
) | ||
|
||
func RecordServer(server *http.Server, request *http.Request) *httptest.ResponseRecorder { | ||
recorder := httptest.NewRecorder() | ||
server.Handler.ServeHTTP(recorder, request) | ||
|
||
return recorder | ||
} | ||
|
||
func RecordHandler(handler http.Handler, request *http.Request) *httptest.ResponseRecorder { | ||
recorder := httptest.NewRecorder() | ||
handler.ServeHTTP(recorder, request) | ||
|
||
return recorder | ||
} | ||
|
||
func Record(handler Handler, request *http.Request) *httptest.ResponseRecorder { | ||
return RecordHandler(handler, request) | ||
} |
Oops, something went wrong.