From ff299915d93ba2dd958789b5c3fc2c614981f521 Mon Sep 17 00:00:00 2001 From: David Dollar Date: Tue, 6 Oct 2015 21:20:22 -0400 Subject: [PATCH] packageify httperr --- api/controllers/api.go | 9 ++-- api/controllers/apps.go | 37 +++++++------- api/controllers/builds.go | 45 ++++++++--------- api/controllers/controllers.go | 23 +++++---- api/controllers/environment.go | 27 +++++----- api/controllers/formation.go | 17 ++++--- api/controllers/processes.go | 49 ++++++++++--------- api/controllers/releases.go | 29 +++++------ api/controllers/services.go | 35 ++++++------- api/controllers/switch.go | 8 ++- api/controllers/system.go | 21 ++++---- .../error.go => httperr/httperr.go} | 28 +++++------ 12 files changed, 170 insertions(+), 158 deletions(-) rename api/{controllers/error.go => httperr/httperr.go} (59%) diff --git a/api/controllers/api.go b/api/controllers/api.go index afe263b41f..60871c50f9 100644 --- a/api/controllers/api.go +++ b/api/controllers/api.go @@ -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) { @@ -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 } diff --git a/api/controllers/apps.go b/api/controllers/apps.go index 5209490f4b..26ceb5eced 100644 --- a/api/controllers/apps.go +++ b/api/controllers/apps.go @@ -5,16 +5,17 @@ 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) @@ -22,27 +23,27 @@ func AppList(rw http.ResponseWriter, r *http.Request) *HttpError { 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{ @@ -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) diff --git a/api/controllers/builds.go b/api/controllers/builds.go index 2ba0a455e2..63802e965f 100644 --- a/api/controllers/builds.go +++ b/api/controllers/builds.go @@ -9,6 +9,7 @@ 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" @@ -16,29 +17,29 @@ import ( "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"] @@ -46,41 +47,41 @@ func BuildGet(rw http.ResponseWriter, r *http.Request) *HttpError { _, 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) @@ -88,14 +89,14 @@ func BuildCreate(rw http.ResponseWriter, r *http.Request) *HttpError { 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) @@ -103,7 +104,7 @@ 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) } @@ -115,16 +116,16 @@ 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"] @@ -132,13 +133,13 @@ func BuildLogs(ws *websocket.Conn) *HttpError { _, 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 @@ -146,7 +147,7 @@ func BuildLogs(ws *websocket.Conn) *HttpError { client, err := docker.NewClient("unix:///var/run/docker.sock") if err != nil { - return ServerError(err) + return httperr.Server(err) } r, w := io.Pipe() @@ -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) { diff --git a/api/controllers/controllers.go b/api/controllers/controllers.go index c6b3e72056..2046ab3151 100644 --- a/api/controllers/controllers.go +++ b/api/controllers/controllers.go @@ -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 { @@ -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 { @@ -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 diff --git a/api/controllers/environment.go b/api/controllers/environment.go index 00156af56e..974091aca1 100644 --- a/api/controllers/environment.go +++ b/api/controllers/environment.go @@ -4,27 +4,28 @@ import ( "io/ioutil" "net/http" + "github.com/convox/rack/api/httperr" "github.com/convox/rack/api/models" "github.com/gorilla/mux" ) -func EnvironmentList(rw http.ResponseWriter, r *http.Request) *HttpError { +func EnvironmentList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] env, err := models.GetEnvironment(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, env) } -func EnvironmentSet(rw http.ResponseWriter, r *http.Request) *HttpError { +func EnvironmentSet(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] @@ -32,31 +33,31 @@ func EnvironmentSet(rw http.ResponseWriter, r *http.Request) *HttpError { _, err := models.GetEnvironment(app) if awsError(err) == "ValidationError" { - return HttpErrorf(404, "no such app: %s", app) + return httperr.Errorf(404, "no such app: %s", app) } body, err := ioutil.ReadAll(r.Body) if err != nil { - return ServerError(err) + return httperr.Server(err) } err = models.PutEnvironment(app, models.LoadEnvironment(body)) if err != nil { - return ServerError(err) + return httperr.Server(err) } env, err := models.GetEnvironment(app) if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, env) } -func EnvironmentDelete(rw http.ResponseWriter, r *http.Request) *HttpError { +func EnvironmentDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] name := vars["name"] @@ -64,11 +65,11 @@ func EnvironmentDelete(rw http.ResponseWriter, r *http.Request) *HttpError { env, err := models.GetEnvironment(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) } delete(env, name) @@ -76,13 +77,13 @@ func EnvironmentDelete(rw http.ResponseWriter, r *http.Request) *HttpError { err = models.PutEnvironment(app, env) if err != nil { - return ServerError(err) + return httperr.Server(err) } env, err = models.GetEnvironment(app) if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, env) diff --git a/api/controllers/formation.go b/api/controllers/formation.go index 162461ffd5..2d009f2967 100644 --- a/api/controllers/formation.go +++ b/api/controllers/formation.go @@ -5,29 +5,30 @@ import ( "strings" "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/convox/rack/api/httperr" "github.com/convox/rack/api/models" "github.com/gorilla/mux" ) -func FormationList(rw http.ResponseWriter, r *http.Request) *HttpError { +func FormationList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] _, 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) } formation, err := models.ListFormation(app) if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, formation) } -func FormationSet(rw http.ResponseWriter, r *http.Request) *HttpError { +func FormationSet(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] process := vars["process"] @@ -37,7 +38,7 @@ func FormationSet(rw http.ResponseWriter, r *http.Request) *HttpError { _, 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.SetFormation(app, process, count, memory) @@ -46,15 +47,15 @@ func FormationSet(rw http.ResponseWriter, r *http.Request) *HttpError { if ae.Code() == "ValidationError" { switch { case strings.Index(ae.Error(), "No updates are to be performed") > -1: - return HttpErrorf(403, "no updates are to be performed: %s", app) + return httperr.Errorf(403, "no updates are to be performed: %s", app) case strings.Index(ae.Error(), "can not be updated") > -1: - return HttpErrorf(403, "app is already updating: %s", app) + return httperr.Errorf(403, "app is already updating: %s", app) } } } if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderSuccess(rw) diff --git a/api/controllers/processes.go b/api/controllers/processes.go index 1334ca93ad..75ff59141e 100644 --- a/api/controllers/processes.go +++ b/api/controllers/processes.go @@ -4,24 +4,25 @@ import ( "net/http" "sort" + "github.com/convox/rack/api/httperr" "github.com/convox/rack/api/models" "github.com/gorilla/mux" "golang.org/x/net/websocket" ) -func ProcessList(rw http.ResponseWriter, r *http.Request) *HttpError { +func ProcessList(rw http.ResponseWriter, r *http.Request) *httperr.Error { app := mux.Vars(r)["app"] _, 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) } processes, err := models.ListProcesses(app) if err != nil { - return ServerError(err) + return httperr.Server(err) } final := models.Processes{} @@ -37,7 +38,7 @@ func ProcessList(rw http.ResponseWriter, r *http.Request) *HttpError { err := <-errch if err != nil { - return ServerError(err) + return httperr.Server(err) } final = append(final, <-psch) @@ -48,7 +49,7 @@ func ProcessList(rw http.ResponseWriter, r *http.Request) *HttpError { return RenderJson(rw, final) } -func ProcessShow(rw http.ResponseWriter, r *http.Request) *HttpError { +func ProcessShow(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] process := vars["process"] @@ -56,25 +57,25 @@ func ProcessShow(rw http.ResponseWriter, r *http.Request) *HttpError { _, 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) } p, err := models.GetProcess(app, process) if err != nil { - return ServerError(err) + return httperr.Server(err) } err = p.FetchStats() if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, p) } -func ProcessExecAttached(ws *websocket.Conn) *HttpError { +func ProcessExecAttached(ws *websocket.Conn) *httperr.Error { vars := mux.Vars(ws.Request()) app := vars["app"] pid := vars["pid"] @@ -83,17 +84,17 @@ func ProcessExecAttached(ws *websocket.Conn) *HttpError { 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) } - return ServerError(a.ExecAttached(pid, command, ws)) + return httperr.Server(a.ExecAttached(pid, command, ws)) } -func ProcessRunDetached(rw http.ResponseWriter, r *http.Request) *HttpError { +func ProcessRunDetached(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] process := vars["process"] @@ -102,19 +103,19 @@ func ProcessRunDetached(rw http.ResponseWriter, r *http.Request) *HttpError { 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) } err = a.RunDetached(process, command) if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderSuccess(rw) } -func ProcessRunAttached(ws *websocket.Conn) *HttpError { +func ProcessRunAttached(ws *websocket.Conn) *httperr.Error { vars := mux.Vars(ws.Request()) app := vars["app"] process := vars["process"] @@ -123,17 +124,17 @@ func ProcessRunAttached(ws *websocket.Conn) *HttpError { 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) } - return ServerError(a.RunAttached(process, command, ws)) + return httperr.Server(a.RunAttached(process, command, ws)) } -func ProcessStop(rw http.ResponseWriter, r *http.Request) *HttpError { +func ProcessStop(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] process := vars["process"] @@ -141,23 +142,23 @@ func ProcessStop(rw http.ResponseWriter, r *http.Request) *HttpError { _, 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) } ps, err := models.GetProcess(app, process) if err != nil { - return ServerError(err) + return httperr.Server(err) } if ps == nil { - return HttpErrorf(404, "no such process: %s", process) + return httperr.Errorf(404, "no such process: %s", process) } err = ps.Stop() if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, ps) diff --git a/api/controllers/releases.go b/api/controllers/releases.go index 892975ca64..9c03300f11 100644 --- a/api/controllers/releases.go +++ b/api/controllers/releases.go @@ -6,34 +6,35 @@ import ( "strings" "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/convox/rack/api/httperr" "github.com/convox/rack/api/models" "github.com/gorilla/mux" ) -func ReleaseList(rw http.ResponseWriter, r *http.Request) *HttpError { +func ReleaseList(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] _, 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) } releases, err := models.ListReleases(app) if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, releases) } -func ReleaseShow(rw http.ResponseWriter, r *http.Request) *HttpError { +func ReleaseShow(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] release := vars["release"] @@ -41,25 +42,25 @@ func ReleaseShow(rw http.ResponseWriter, r *http.Request) *HttpError { _, 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) } rr, err := models.GetRelease(app, release) if err != nil && strings.HasPrefix(err.Error(), "no such release") { - return HttpErrorf(404, "no such release: %s", release) + return httperr.Errorf(404, "no such release: %s", release) } fmt.Printf("err %+v\n", err) if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, rr) } -func ReleasePromote(rw http.ResponseWriter, r *http.Request) *HttpError { +func ReleasePromote(rw http.ResponseWriter, r *http.Request) *httperr.Error { vars := mux.Vars(r) app := vars["app"] release := vars["release"] @@ -67,27 +68,27 @@ func ReleasePromote(rw http.ResponseWriter, r *http.Request) *HttpError { _, 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) } rr, err := models.GetRelease(app, release) if err != nil && strings.HasPrefix(err.Error(), "no such release") { - return HttpErrorf(404, "no such release: %s", release) + return httperr.Errorf(404, "no such release: %s", release) } if err != nil { - return ServerError(err) + return httperr.Server(err) } err = rr.Promote() if awsError(err) == "ValidationError" { - return HttpErrorf(403, err.(awserr.Error).Message()) + return httperr.Errorf(403, err.(awserr.Error).Message()) } if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, rr) diff --git a/api/controllers/services.go b/api/controllers/services.go index d296dfb5d6..2c20a7da1f 100644 --- a/api/controllers/services.go +++ b/api/controllers/services.go @@ -4,38 +4,39 @@ import ( "net/http" "strings" + "github.com/convox/rack/api/httperr" "github.com/convox/rack/api/models" "github.com/gorilla/mux" "golang.org/x/net/websocket" ) -func ServiceList(rw http.ResponseWriter, r *http.Request) *HttpError { +func ServiceList(rw http.ResponseWriter, r *http.Request) *httperr.Error { services, err := models.ListServices() if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, services) } -func ServiceShow(rw http.ResponseWriter, r *http.Request) *HttpError { +func ServiceShow(rw http.ResponseWriter, r *http.Request) *httperr.Error { service := mux.Vars(r)["service"] s, err := models.GetService(service) if awsError(err) == "ValidationError" { - return HttpErrorf(404, "no such service: %s", service) + return httperr.Errorf(404, "no such service: %s", service) } if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, s) } -func ServiceCreate(rw http.ResponseWriter, r *http.Request) *HttpError { +func ServiceCreate(rw http.ResponseWriter, r *http.Request) *httperr.Error { name := GetForm(r, "name") t := GetForm(r, "type") @@ -47,61 +48,61 @@ func ServiceCreate(rw http.ResponseWriter, r *http.Request) *HttpError { err := service.Create() if err != nil && strings.HasSuffix(err.Error(), "not found") { - return HttpErrorf(403, "invalid service type: %s", t) + return httperr.Errorf(403, "invalid service type: %s", t) } if err != nil && awsError(err) == "ValidationError" { - return HttpErrorf(403, "invalid service name: %s", name) + return httperr.Errorf(403, "invalid service name: %s", name) } if err != nil { - return ServerError(err) + return httperr.Server(err) } service, err = models.GetService(name) if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, service) } -func ServiceDelete(rw http.ResponseWriter, r *http.Request) *HttpError { +func ServiceDelete(rw http.ResponseWriter, r *http.Request) *httperr.Error { service := mux.Vars(r)["service"] s, err := models.GetService(service) if awsError(err) == "ValidationError" { - return HttpErrorf(404, "no such service: %s", service) + return httperr.Errorf(404, "no such service: %s", service) } if err != nil { - return ServerError(err) + return httperr.Server(err) } err = s.Delete() if err != nil { - return ServerError(err) + return httperr.Server(err) } s, err = models.GetService(service) if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, s) } -func ServiceLogs(ws *websocket.Conn) *HttpError { +func ServiceLogs(ws *websocket.Conn) *httperr.Error { service := mux.Vars(ws.Request())["service"] s, err := models.GetService(service) if err != nil { - return ServerError(err) + return httperr.Server(err) } logs := make(chan []byte) diff --git a/api/controllers/switch.go b/api/controllers/switch.go index 1d1e6e2666..11d78d0a7f 100644 --- a/api/controllers/switch.go +++ b/api/controllers/switch.go @@ -1,8 +1,12 @@ package controllers -import "net/http" +import ( + "net/http" -func Switch(w http.ResponseWriter, r *http.Request) *HttpError { + "github.com/convox/rack/api/httperr" +) + +func Switch(w http.ResponseWriter, r *http.Request) *httperr.Error { response := map[string]string{ "source": "rack", } diff --git a/api/controllers/system.go b/api/controllers/system.go index 5f04dcd8b4..44bbfc107e 100644 --- a/api/controllers/system.go +++ b/api/controllers/system.go @@ -5,38 +5,39 @@ import ( "strconv" "strings" + "github.com/convox/rack/api/httperr" "github.com/convox/rack/api/models" ) func init() { } -func SystemShow(rw http.ResponseWriter, r *http.Request) *HttpError { +func SystemShow(rw http.ResponseWriter, r *http.Request) *httperr.Error { rack, err := models.GetSystem() if awsError(err) == "ValidationError" { - return HttpErrorf(404, "no such stack: %s", rack) + return httperr.Errorf(404, "no such stack: %s", rack) } if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, rack) } -func SystemUpdate(rw http.ResponseWriter, r *http.Request) *HttpError { +func SystemUpdate(rw http.ResponseWriter, r *http.Request) *httperr.Error { rack, err := models.GetSystem() if err != nil { - return ServerError(err) + return httperr.Server(err) } if count := GetForm(r, "count"); count != "" { count, err := strconv.Atoi(count) if err != nil { - return ServerError(err) + return httperr.Server(err) } rack.Count = count @@ -55,20 +56,20 @@ func SystemUpdate(rw http.ResponseWriter, r *http.Request) *HttpError { if awsError(err) == "ValidationError" { switch { case strings.Index(err.Error(), "No updates are to be performed") > -1: - return HttpErrorf(403, "no system updates are to be performed") + return httperr.Errorf(403, "no system updates are to be performed") case strings.Index(err.Error(), "can not be updated") > -1: - return HttpErrorf(403, "system is already updating") + return httperr.Errorf(403, "system is already updating") } } if err != nil { - return ServerError(err) + return httperr.Server(err) } rack, err = models.GetSystem() if err != nil { - return ServerError(err) + return httperr.Server(err) } return RenderJson(rw, rack) diff --git a/api/controllers/error.go b/api/httperr/httperr.go similarity index 59% rename from api/controllers/error.go rename to api/httperr/httperr.go index d2948cb83a..7128363a06 100644 --- a/api/controllers/error.go +++ b/api/httperr/httperr.go @@ -1,4 +1,4 @@ -package controllers +package httperr import ( "fmt" @@ -10,19 +10,19 @@ import ( const ErrorHandlerSkipLines = 7 -type HttpError struct { +type Error struct { code int err error stack rollbar.Stack trace []string } -func NewHttpError(code int, err error) *HttpError { +func New(code int, err error) *Error { if err == nil { return nil } - e := &HttpError{ + e := &Error{ code: code, err: err, stack: rollbar.BuildStack(1), @@ -32,36 +32,36 @@ func NewHttpError(code int, err error) *HttpError { return e } -func ServerError(err error) *HttpError { - return NewHttpError(500, err) +func Server(err error) *Error { + return New(500, err) } -func HttpErrorf(code int, format string, args ...interface{}) *HttpError { - return NewHttpError(code, fmt.Errorf(format, args...)) +func Errorf(code int, format string, args ...interface{}) *Error { + return New(code, fmt.Errorf(format, args...)) } -func (e *HttpError) Code() int { +func (e *Error) Code() int { return e.code } -func (e *HttpError) Error() string { +func (e *Error) Error() string { return e.err.Error() } -func (e *HttpError) Save() error { +func (e *Error) Save() error { rollbar.ErrorWithStack(rollbar.ERR, e.err, e.stack) return nil } -func (e *HttpError) Trace() []string { +func (e *Error) Trace() []string { return e.trace } -func (e *HttpError) ServerError() bool { +func (e *Error) Server() bool { return e.code >= 500 && e.code < 600 } -func (e *HttpError) UserError() bool { +func (e *Error) User() bool { return e.code >= 400 && e.code < 500 }