Skip to content

Commit

Permalink
Merge pull request #7 from ww24/fix/api-error-handling
Browse files Browse the repository at this point in the history
fix error handling
  • Loading branch information
ww24 authored Dec 23, 2016
2 parents 696a237 + eeb40e4 commit f5dc3d1
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 52 deletions.
94 changes: 94 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"net/http"

"github.com/labstack/echo"
"github.com/ww24/lirc-web-api/lirc"
)

type signal struct {
Remote string `json:"remote"`
Name string `json:"name"`
}

func apiv1(g *echo.Group) {
g.GET("/", func(c echo.Context) (err error) {
signals, err := fetchSignals()
if err != nil {
return wrapError(err)
}

return &response{
code: http.StatusOK,
Status: "ok",
Signals: signals,
}
})

g.POST("/", func(c echo.Context) (err error) {
sig := new(signal)
if err = c.Bind(sig); err != nil {
return wrapError(err)
}

client, err := lirc.New()
if err != nil {
return wrapError(err)
}
defer client.Close()

replies, err := client.List(sig.Remote, sig.Name)
if err != nil {
return wrapError(err)
}
if len(replies) == 0 {
return &response{
code: http.StatusBadRequest,
Status: "ng",
Message: "invalid signal",
}
}

err = client.SendOnce(sig.Remote, sig.Name)
if err != nil {
return wrapError(err)
}

return &response{
code: http.StatusOK,
Status: "ok",
}
})
}

func fetchSignals() (signals []signal, err error) {
client, err := lirc.New()
if err != nil {
return
}
defer client.Close()

remotes, err := client.List("")
if err != nil {
return
}

signals = make([]signal, 0, len(remotes)*2)
for _, remote := range remotes {
var replies []string
replies, err = client.List(remote)
if err != nil {
return
}

for _, reply := range replies {
signals = append(signals, signal{
Remote: remote,
Name: reply,
})
}
}

return
}
84 changes: 33 additions & 51 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,43 @@ import (
"github.com/labstack/echo"
"github.com/labstack/gommon/log"
"github.com/ww24/lirc-web-api/config"
"github.com/ww24/lirc-web-api/lirc"
)

var (
// -ldflags "-X main.version=$API_VERSION"
version string

isAPIVersion bool
apiPort int
outputAPIVersion bool
apiPort int
)

type response struct {
code int
Status string `json:"status"`
Message string `json:"message"`
List []string `json:"list,omitempty"`
Message string `json:"message,omitempty"`
Signals []signal `json:"signals,omitempty"`
}

func (res *response) Error() string {
return res.Message
}

func wrapError(err error) error {
return &response{
code: http.StatusInternalServerError,
Status: "ng",
Message: err.Error(),
}
}

func init() {
flag.BoolVar(&isAPIVersion, "v", false, "output version")
flag.BoolVar(&outputAPIVersion, "v", false, "output version")
flag.IntVar(&apiPort, "p", 3000, "set API port")
flag.Parse()
}

func main() {
if isAPIVersion {
if outputAPIVersion {
fmt.Println(version)
return
}
Expand All @@ -44,18 +56,18 @@ func main() {
e.Logger.Infof("API version: %s", version)
e.Logger.Infof("Running mode: %s", config.Mode)

// error handling middleware
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
// create api v1 group and set error handling middleware
apiv1g := e.Group("/api/v1", func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
msg := "unknown"

defer func() {
cause := recover()
if cause != nil {
e.Logger.Errorf("Panic:%v", cause)
if err, ok := cause.(error); ok && config.IsDev() {
msg = err.Error()
}
e.Logger.Errorf("Panic:%v", cause)
c.JSON(http.StatusInternalServerError, &response{
Status: "ng",
Message: msg,
Expand All @@ -65,52 +77,22 @@ func main() {

err := next(c)
if err != nil {
e.Logger.Errorf("InternalServerError:%s", err)
if config.IsDev() {
msg = err.Error()
if res, ok := err.(*response); ok {
if res.Status == "ok" {
return c.JSON(res.code, res)
}

e.Logger.Errorf("InternalServerError:%s", res)
if config.IsProd() {
res.Message = msg
}
return c.JSON(http.StatusInternalServerError, res)
}
return c.JSON(http.StatusInternalServerError, &response{
Status: "ng",
Message: msg,
})
}
return err
}
})

e.GET("/", func(c echo.Context) (err error) {
client, err := lirc.New()
if err != nil {
return
}

replies, err := client.List("")
if err != nil {
return
}

return c.JSON(http.StatusOK, &response{
Status: "ok",
List: replies,
})
})

// TODO: implement
e.POST("/", func(c echo.Context) (err error) {
client, err := lirc.New()
if err != nil {
return
}

err = client.SendOnce("aircon", "on")
if err != nil {
return
}

return c.JSON(http.StatusOK, &response{
Status: "ok",
})
})
apiv1(apiv1g)

e.Logger.Fatal(e.Start(":" + strconv.Itoa(apiPort)))
}
2 changes: 1 addition & 1 deletion wercker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build:
steps:
- script:
name: set API_VERSION
code: export API_VERSION="v0.1.3"
code: export API_VERSION="v0.2.0"

- install-packages:
packages: lirc
Expand Down

0 comments on commit f5dc3d1

Please sign in to comment.