Skip to content

Commit

Permalink
packageify httperr
Browse files Browse the repository at this point in the history
  • Loading branch information
ddollar committed Oct 7, 2015
1 parent c5867dc commit ff29991
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 158 deletions.
9 changes: 5 additions & 4 deletions api/controllers/api.go
Expand Up @@ -8,12 +8,13 @@ import (
"os"
"strings"

"github.com/convox/rack/api/httperr"
"github.com/ddollar/logger"
"golang.org/x/net/websocket"
)

type ApiHandlerFunc func(http.ResponseWriter, *http.Request) *HttpError
type ApiWebsocketFunc func(*websocket.Conn) *HttpError
type ApiHandlerFunc func(http.ResponseWriter, *http.Request) *httperr.Error
type ApiWebsocketFunc func(*websocket.Conn) *httperr.Error

func api(at string, handler ApiHandlerFunc) http.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -45,8 +46,8 @@ func api(at string, handler ApiHandlerFunc) http.HandlerFunc {
}
}

func logError(log *logger.Logger, err *HttpError) {
if err.UserError() {
func logError(log *logger.Logger, err *httperr.Error) {
if err.User() {
log.Log("state=error type=user message=%q", err.Error())
return
}
Expand Down
37 changes: 19 additions & 18 deletions api/controllers/apps.go
Expand Up @@ -5,44 +5,45 @@ import (
"sort"
"strings"

"github.com/convox/rack/api/httperr"
"github.com/convox/rack/api/models"
"github.com/gorilla/mux"
"golang.org/x/net/websocket"
)

func AppList(rw http.ResponseWriter, r *http.Request) *HttpError {
func AppList(rw http.ResponseWriter, r *http.Request) *httperr.Error {
apps, err := models.ListApps()

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

sort.Sort(apps)

return RenderJson(rw, apps)
}

func AppShow(rw http.ResponseWriter, r *http.Request) *HttpError {
func AppShow(rw http.ResponseWriter, r *http.Request) *httperr.Error {
app := mux.Vars(r)["app"]

a, err := models.GetApp(mux.Vars(r)["app"])

if awsError(err) == "ValidationError" {
return HttpErrorf(404, "no such app: %s", app)
return httperr.Errorf(404, "no such app: %s", app)
}

if err != nil && strings.HasPrefix(err.Error(), "no such app") {
return HttpErrorf(404, "no such app: %s", app)
return httperr.Errorf(404, "no such app: %s", app)
}

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

return RenderJson(rw, a)
}

func AppCreate(rw http.ResponseWriter, r *http.Request) *HttpError {
func AppCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error {
name := r.FormValue("name")

app := &models.App{
Expand All @@ -55,58 +56,58 @@ func AppCreate(rw http.ResponseWriter, r *http.Request) *HttpError {
app, err := models.GetApp(name)

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

return HttpErrorf(403, "there is already an app named %s (%s)", name, app.Status)
return httperr.Errorf(403, "there is already an app named %s (%s)", name, app.Status)
}

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

app, err = models.GetApp(name)

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

return RenderJson(rw, app)
}

func AppDelete(rw http.ResponseWriter, r *http.Request) *HttpError {
func AppDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error {
name := mux.Vars(r)["app"]

app, err := models.GetApp(name)

if awsError(err) == "ValidationError" {
return HttpErrorf(404, "no such app: %s", name)
return httperr.Errorf(404, "no such app: %s", name)
}

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

err = app.Delete()

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

return RenderSuccess(rw)
}

func AppLogs(ws *websocket.Conn) *HttpError {
func AppLogs(ws *websocket.Conn) *httperr.Error {
app := mux.Vars(ws.Request())["app"]

a, err := models.GetApp(app)

if awsError(err) == "ValidationError" {
return HttpErrorf(404, "no such app: %s", app)
return httperr.Errorf(404, "no such app: %s", app)
}

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

logs := make(chan []byte)
Expand Down
45 changes: 23 additions & 22 deletions api/controllers/builds.go
Expand Up @@ -9,101 +9,102 @@ import (
"strings"
"time"

"github.com/convox/rack/api/httperr"
"github.com/convox/rack/api/models"
"github.com/ddollar/logger"
docker "github.com/fsouza/go-dockerclient"
"github.com/gorilla/mux"
"golang.org/x/net/websocket"
)

func BuildList(rw http.ResponseWriter, r *http.Request) *HttpError {
func BuildList(rw http.ResponseWriter, r *http.Request) *httperr.Error {
app := mux.Vars(r)["app"]

builds, err := models.ListBuilds(app)

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

_, err = models.GetApp(app)

if awsError(err) == "ValidationError" {
return HttpErrorf(404, "no such app: %s", app)
return httperr.Errorf(404, "no such app: %s", app)
}

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

return RenderJson(rw, builds)
}

func BuildGet(rw http.ResponseWriter, r *http.Request) *HttpError {
func BuildGet(rw http.ResponseWriter, r *http.Request) *httperr.Error {
vars := mux.Vars(r)
app := vars["app"]
build := vars["build"]

_, err := models.GetApp(app)

if awsError(err) == "ValidationError" {
return HttpErrorf(404, "no such app: %s", app)
return httperr.Errorf(404, "no such app: %s", app)
}

b, err := models.GetBuild(app, build)

if err != nil && strings.HasPrefix(err.Error(), "no such build") {
return HttpErrorf(404, err.Error())
return httperr.Errorf(404, err.Error())
}

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

return RenderJson(rw, b)
}

func BuildCreate(rw http.ResponseWriter, r *http.Request) *HttpError {
func BuildCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error {
build := models.NewBuild(mux.Vars(r)["app"])

err := r.ParseMultipartForm(50 * 1024 * 1024)

if err != nil && err != http.ErrNotMultipart {
return ServerError(err)
return httperr.Server(err)
}

err = build.Save()

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

resources, err := models.ListResources(os.Getenv("RACK"))

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

ch := make(chan error)

source, _, err := r.FormFile("source")

if err != nil && err != http.ErrMissingFile && err != http.ErrNotMultipart {
return ServerError(err)
return httperr.Server(err)
}

if source != nil {
err = models.S3PutFile(resources["RegistryBucket"].Id, fmt.Sprintf("builds/%s.tgz", build.Id), source, false)

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

go build.ExecuteLocal(source, ch)

err = <-ch

if err != nil {
return ServerError(err)
return httperr.Server(err)
} else {
return RenderJson(rw, build)
}
Expand All @@ -115,38 +116,38 @@ func BuildCreate(rw http.ResponseWriter, r *http.Request) *HttpError {
err = <-ch

if err != nil {
return ServerError(err)
return httperr.Server(err)
} else {
return RenderJson(rw, build)
}
}

return HttpErrorf(403, "no source or repo")
return httperr.Errorf(403, "no source or repo")
}

func BuildLogs(ws *websocket.Conn) *HttpError {
func BuildLogs(ws *websocket.Conn) *httperr.Error {
vars := mux.Vars(ws.Request())
app := vars["app"]
build := vars["build"]

_, err := models.GetApp(app)

if awsError(err) == "ValidationError" {
return HttpErrorf(404, "no such app: %s", app)
return httperr.Errorf(404, "no such app: %s", app)
}

_, err = models.GetBuild(app, build)

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

// proxy to docker container logs
// https://docs.docker.com/reference/api/docker_remote_api_v1.19/#get-container-logs
client, err := docker.NewClient("unix:///var/run/docker.sock")

if err != nil {
return ServerError(err)
return httperr.Server(err)
}

r, w := io.Pipe()
Expand All @@ -169,7 +170,7 @@ func BuildLogs(ws *websocket.Conn) *HttpError {

quit <- true

return ServerError(err)
return httperr.Server(err)
}

func scanLines(r io.Reader, ws *websocket.Conn) {
Expand Down
23 changes: 11 additions & 12 deletions api/controllers/controllers.go
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"

"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/convox/rack/api/httperr"
)

func awsError(err error) string {
Expand All @@ -26,15 +27,13 @@ func GetForm(r *http.Request, name string) string {
}
}

func RenderError(rw http.ResponseWriter, err error) *HttpError {
if err != nil {
http.Error(rw, fmt.Sprintf(`{"error":%q}`, err.Error()), http.StatusInternalServerError)
}
func RenderError(rw http.ResponseWriter, err error) *httperr.Error {
rw.Write([]byte(fmt.Sprintf(`{"error":%q}`, err.Error())))

return ServerError(err)
return httperr.Server(err)
}

func RenderJson(rw http.ResponseWriter, object interface{}) *HttpError {
func RenderJson(rw http.ResponseWriter, object interface{}) *httperr.Error {
data, err := json.MarshalIndent(object, "", " ")

if err != nil {
Expand All @@ -47,22 +46,22 @@ func RenderJson(rw http.ResponseWriter, object interface{}) *HttpError {

_, err = rw.Write(data)

return ServerError(err)
return httperr.Server(err)
}

func RenderText(rw http.ResponseWriter, text string) *HttpError {
func RenderText(rw http.ResponseWriter, text string) *httperr.Error {
_, err := rw.Write([]byte(text))

return ServerError(err)
return httperr.Server(err)
}

func RenderSuccess(rw http.ResponseWriter) *HttpError {
func RenderSuccess(rw http.ResponseWriter) *httperr.Error {
_, err := rw.Write([]byte(`{"success":true}`))

return ServerError(err)
return httperr.Server(err)
}

func Redirect(rw http.ResponseWriter, r *http.Request, path string) *HttpError {
func Redirect(rw http.ResponseWriter, r *http.Request, path string) *httperr.Error {
http.Redirect(rw, r, path, http.StatusFound)

return nil
Expand Down

0 comments on commit ff29991

Please sign in to comment.