Add more error handling for unknown robots, devices and connections

This commit is contained in:
Adrian Zankich 2014-12-07 08:54:50 -08:00
parent f1e94b5a1a
commit 5dd554dbc6
2 changed files with 114 additions and 52 deletions

View File

@ -2,6 +2,7 @@ package api
import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
@ -182,32 +183,45 @@ func (a *api) robots(res http.ResponseWriter, req *http.Request) {
// robot returns route handler.
// Writes JSON with robot representation
func (a *api) robot(res http.ResponseWriter, req *http.Request) {
a.writeJSON(map[string]interface{}{"robot": gobot.NewJSONRobot(a.gobot.Robot(req.URL.Query().Get(":robot")))}, res)
if robot, err := a.jsonRobotFor(req.URL.Query().Get(":robot")); err != nil {
a.writeJSON(map[string]interface{}{"error": err.Error()}, res)
} else {
a.writeJSON(map[string]interface{}{"robot": robot}, res)
}
}
// robotCommands returns commands route handler
// Writes JSON with robot commands representation
func (a *api) robotCommands(res http.ResponseWriter, req *http.Request) {
a.writeJSON(map[string]interface{}{"commands": gobot.NewJSONRobot(a.gobot.Robot(req.URL.Query().Get(":robot"))).Commands}, res)
if robot, err := a.jsonRobotFor(req.URL.Query().Get(":robot")); err != nil {
a.writeJSON(map[string]interface{}{"error": err.Error()}, res)
} else {
a.writeJSON(map[string]interface{}{"commands": robot.Commands}, res)
}
}
// robotDevices returns devices route handler.
// Writes JSON with robot devices representation
func (a *api) robotDevices(res http.ResponseWriter, req *http.Request) {
jsonDevices := []*gobot.JSONDevice{}
a.gobot.Robot(req.URL.Query().Get(":robot")).Devices().Each(func(d gobot.Device) {
jsonDevices = append(jsonDevices, gobot.NewJSONDevice(d))
})
a.writeJSON(map[string]interface{}{"devices": jsonDevices}, res)
if robot := a.gobot.Robot(req.URL.Query().Get(":robot")); robot != nil {
jsonDevices := []*gobot.JSONDevice{}
robot.Devices().Each(func(d gobot.Device) {
jsonDevices = append(jsonDevices, gobot.NewJSONDevice(d))
})
a.writeJSON(map[string]interface{}{"devices": jsonDevices}, res)
} else {
a.writeJSON(map[string]interface{}{"error": "No Robot found with the name " + req.URL.Query().Get(":robot")}, res)
}
}
// robotDevice returns device route handler.
// Writes JSON with robot device representation
func (a *api) robotDevice(res http.ResponseWriter, req *http.Request) {
a.writeJSON(
map[string]interface{}{"device": gobot.NewJSONDevice(a.gobot.Robot(req.URL.Query().Get(":robot")).
Device(req.URL.Query().Get(":device")))}, res,
)
if device, err := a.jsonDeviceFor(req.URL.Query().Get(":robot"), req.URL.Query().Get(":device")); err != nil {
a.writeJSON(map[string]interface{}{"error": err.Error()}, res)
} else {
a.writeJSON(map[string]interface{}{"device": device}, res)
}
}
// robotDeviceEvent returns device event route handler.
@ -224,52 +238,64 @@ func (a *api) robotDeviceEvent(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Cache-Control", "no-cache")
res.Header().Set("Connection", "keep-alive")
gobot.On(a.gobot.Robot(req.URL.Query().Get(":robot")).
Device(req.URL.Query().Get(":device")).(gobot.Eventer).Event(req.URL.Query().Get(":event")),
func(data interface{}) {
if event := a.gobot.Robot(req.URL.Query().Get(":robot")).
Device(req.URL.Query().Get(":device")).(gobot.Eventer).
Event(req.URL.Query().Get(":event")); event != nil {
gobot.On(event, func(data interface{}) {
d, _ := json.Marshal(data)
msg <- string(d)
})
for {
select {
case data := <-msg:
fmt.Fprintf(res, "data: %v\n\n", data)
f.Flush()
case <-closer:
log.Println("Closing connection")
return
for {
select {
case data := <-msg:
fmt.Fprintf(res, "data: %v\n\n", data)
f.Flush()
case <-closer:
log.Println("Closing connection")
return
}
}
} else {
a.writeJSON(map[string]interface{}{
"error": errors.New("No Event found with the name " + req.URL.Query().Get(":event")),
}, res)
}
}
// robotDeviceCommands returns device commands route handler
// writes JSON with robot device commands representation
func (a *api) robotDeviceCommands(res http.ResponseWriter, req *http.Request) {
a.writeJSON(
map[string]interface{}{"commands": gobot.NewJSONDevice(a.gobot.Robot(req.URL.Query().Get(":robot")).
Device(req.URL.Query().Get(":device"))).Commands}, res,
)
if device, err := a.jsonDeviceFor(req.URL.Query().Get(":robot"), req.URL.Query().Get(":device")); err != nil {
a.writeJSON(map[string]interface{}{"error": err.Error()}, res)
} else {
a.writeJSON(map[string]interface{}{"commands": device.Commands}, res)
}
}
// robotConnections returns connections route handler
// writes JSON with robot connections representation
func (a *api) robotConnections(res http.ResponseWriter, req *http.Request) {
jsonConnections := []*gobot.JSONConnection{}
a.gobot.Robot(req.URL.Query().Get(":robot")).Connections().Each(func(c gobot.Connection) {
jsonConnections = append(jsonConnections, gobot.NewJSONConnection(c))
})
a.writeJSON(map[string]interface{}{"connections": jsonConnections}, res)
if robot := a.gobot.Robot(req.URL.Query().Get(":robot")); robot != nil {
robot.Connections().Each(func(c gobot.Connection) {
jsonConnections = append(jsonConnections, gobot.NewJSONConnection(c))
})
a.writeJSON(map[string]interface{}{"connections": jsonConnections}, res)
} else {
a.writeJSON(map[string]interface{}{"error": "No Robot found with the name " + req.URL.Query().Get(":robot")}, res)
}
}
// robotConnection returns connection route handler
// writes JSON with robot connection representation
func (a *api) robotConnection(res http.ResponseWriter, req *http.Request) {
a.writeJSON(
map[string]interface{}{"connection": gobot.NewJSONConnection(a.gobot.Robot(req.URL.Query().Get(":robot")).
Connection(req.URL.Query().Get(":connection")))},
res,
)
if conn, err := a.jsonConnectionFor(req.URL.Query().Get(":robot"), req.URL.Query().Get(":connection")); err != nil {
a.writeJSON(map[string]interface{}{"error": err.Error()}, res)
} else {
a.writeJSON(map[string]interface{}{"connection": conn}, res)
}
}
// executeMcpCommand calls a global command asociated to requested route
@ -282,23 +308,32 @@ func (a *api) executeMcpCommand(res http.ResponseWriter, req *http.Request) {
// executeDeviceCommand calls a device command asociated to requested route
func (a *api) executeDeviceCommand(res http.ResponseWriter, req *http.Request) {
a.executeCommand(
a.gobot.Robot(req.URL.Query().Get(":robot")).
Device(req.URL.Query().Get(":device")).(gobot.Commander).
Command(req.URL.Query().Get(":command")),
res,
req,
)
if _, err := a.jsonDeviceFor(req.URL.Query().Get(":robot"),
req.URL.Query().Get(":device")); err != nil {
a.writeJSON(map[string]interface{}{"error": err.Error()}, res)
} else {
a.executeCommand(
a.gobot.Robot(req.URL.Query().Get(":robot")).
Device(req.URL.Query().Get(":device")).(gobot.Commander).
Command(req.URL.Query().Get(":command")),
res,
req,
)
}
}
// executeRobotCommand calls a robot command asociated to requested route
func (a *api) executeRobotCommand(res http.ResponseWriter, req *http.Request) {
a.executeCommand(
a.gobot.Robot(req.URL.Query().Get(":robot")).
Command(req.URL.Query().Get(":command")),
res,
req,
)
if _, err := a.jsonRobotFor(req.URL.Query().Get(":robot")); err != nil {
a.writeJSON(map[string]interface{}{"error": err.Error()}, res)
} else {
a.executeCommand(
a.gobot.Robot(req.URL.Query().Get(":robot")).
Command(req.URL.Query().Get(":command")),
res,
req,
)
}
}
// executeCommand writes JSON response with `f` returned value.
@ -313,7 +348,7 @@ func (a *api) executeCommand(f func(map[string]interface{}) interface{},
if f != nil {
a.writeJSON(map[string]interface{}{"result": f(body)}, res)
} else {
a.writeJSON("Unknown Command", res)
a.writeJSON(map[string]interface{}{"error": "Unknown Command"}, res)
}
}
@ -330,3 +365,30 @@ func (a *api) Debug() {
log.Println(req)
})
}
func (a *api) jsonRobotFor(name string) (jrobot *gobot.JSONRobot, err error) {
if robot := a.gobot.Robot(name); robot != nil {
jrobot = gobot.NewJSONRobot(robot)
} else {
err = errors.New("No Robot found with the name " + name)
}
return
}
func (a *api) jsonDeviceFor(robot string, name string) (jdevice *gobot.JSONDevice, err error) {
if device := a.gobot.Robot(robot).Device(name); device != nil {
jdevice = gobot.NewJSONDevice(device)
} else {
err = errors.New("No Device found with the name " + name)
}
return
}
func (a *api) jsonConnectionFor(robot string, name string) (jconnection *gobot.JSONConnection, err error) {
if connection := a.gobot.Robot(robot).Connection(name); connection != nil {
jconnection = gobot.NewJSONConnection(connection)
} else {
err = errors.New("No Connection found with the name " + name)
}
return
}

View File

@ -104,7 +104,7 @@ func TestExecuteMcpCommand(t *testing.T) {
a.ServeHTTP(response, request)
json.NewDecoder(response.Body).Decode(&body)
gobot.Assert(t, body, "Unknown Command")
gobot.Assert(t, body.(map[string]interface{})["error"], "Unknown Command")
}
func TestRobots(t *testing.T) {
@ -176,7 +176,7 @@ func TestExecuteRobotCommand(t *testing.T) {
a.ServeHTTP(response, request)
json.NewDecoder(response.Body).Decode(&body)
gobot.Assert(t, body, "Unknown Command")
gobot.Assert(t, body.(map[string]interface{})["error"], "Unknown Command")
}
func TestRobotDevice(t *testing.T) {
@ -233,7 +233,7 @@ func TestExecuteRobotDeviceCommand(t *testing.T) {
a.ServeHTTP(response, request)
json.NewDecoder(response.Body).Decode(&body)
gobot.Assert(t, body, "Unknown Command")
gobot.Assert(t, body.(map[string]interface{})["error"], "Unknown Command")
}
func TestRobotConnections(t *testing.T) {