Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance error handling #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ go get gopkg.in/go-playground/validator.v9
```
go get github.com/gorilla/schema
```
- Use the following snippet to parse and validate given input as a struct (see [here](#errors) for errors)
- Use the following snippet to parse and validate given input as a struct (see [here](#invalid-input))
```go
type ListingInput struct {
Limit uint `schema:"limit" validate:"min=0,max=100"`
Expand All @@ -48,7 +48,7 @@ func ParseListingInput(r *http.Request) *ListingInput {

func Validate(input *ListingInput) {
if err := validator.New().Struct(input); err != nil {
panic(throw.InvalidInputError(err.Error(), 1000, 400))
panic(throw.InvalidInputError(err.Error(), 1000))
}
}
```
Expand All @@ -69,15 +69,18 @@ response.JSONError(w, status, errorCode, errorMessage)
```

### Error Handling
- Define errors in the `throw` package at `throw/errors.go` as a struct
- Define errors in the `throw` package

```go
type SomethingWrong struct {
*HTTPError
package throw

type NewError struct {
BaseError
}
```
- For each error, better have a factory method to help make a new instance of the error, i.e.
```go
func SomethingWrongError(m string, c, s uint16) SomethingWrong {
return InvalidInput{&HTTPError{Message: m, Code: c, Status: s}r}
func SomethingWrongError(m string, c uint16) SomethingWrong {
return InvalidInput{&HTTPError{Message: m, Code: c}}
}
```
8 changes: 2 additions & 6 deletions routes/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@ package routes
import (
"net/http"

"github.com/mulkave/go-init/throw"
"github.com/vinelab/go-init/throw"
)

// Serve wraps the features to be served from the routes,
// implements centralised error handling.
func Serve(handler func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
defer func() {
if e := recover(); e != nil {
throw.Handle(e.(throw.Error), w, r)
}
}()
defer throw.HandleHttpRequestErrors(w)

handler(w, r)
}
Expand Down
10 changes: 10 additions & 0 deletions throw/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package throw

type BaseError struct {
Message string
Code uint16
}

func (e BaseError) Error() string {
return e.Message
}
32 changes: 0 additions & 32 deletions throw/errors.go

This file was deleted.

33 changes: 25 additions & 8 deletions throw/handler.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
package throw

import "net/http"

// Handle panics, it prefers to be deferred.
func Handle(e Error, w http.ResponseWriter, r *http.Request) {
switch e.(type) {
case InvalidInput:
err := e.(InvalidInput) // cast to error type
http.Error(w, err.Message, int(err.Status))
import (
"net/http"

"github.com/vinelab/go-init/response"
)

func HandleHttpRequestErrors(w http.ResponseWriter) {

//check if panic happened
if err := recover(); err != nil {
var status uint16
var code uint16

switch err.(type) {
case InvalidInput:
status = 400

err := err.(InvalidInput)
code = err.Code
default:
status = 500
code = 500
}

response.JSONError(w, status, code, err.(error).Error())
}
}
14 changes: 14 additions & 0 deletions throw/invalid-input.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package throw

// InvalidInput specifies that the received input parameters
type InvalidInput struct {
*BaseError
}

func (e InvalidInput) Error() string {
return "Invalid input error: " + e.BaseError.Error()
}

func InvalidInputError(m string, c uint16) InvalidInput {
return InvalidInput{&BaseError{Message: m, Code: c}}
}