Skip to content

Commit

Permalink
Friendly Errors! (#78)
Browse files Browse the repository at this point in the history
Print the error dump on development mode

Fix a bunch of errors sentencing and creation

Add simple error creating functions
  • Loading branch information
natsukagami committed Apr 4, 2020
1 parent 779b140 commit 7ada7ee
Show file tree
Hide file tree
Showing 17 changed files with 102 additions and 57 deletions.
11 changes: 6 additions & 5 deletions server/admin/contest.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"

"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -47,11 +48,11 @@ func (g *Group) getContest(c echo.Context) (*models.Contest, error) {
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("Contest not found: %s", idStr)
}
contest, err := models.GetContest(g.db, id)
if errors.Is(err, sql.ErrNoRows) {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("Contest not found: %d", id)
} else if err != nil {
return nil, err
}
Expand Down Expand Up @@ -99,7 +100,7 @@ func (g *Group) ContestDelete(c echo.Context) error {
return err
}
if err := contest.Delete(g.db); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return err
}
return c.Redirect(http.StatusSeeOther, "/admin/contests")
}
Expand All @@ -113,7 +114,7 @@ func (g *Group) ContestEdit(c echo.Context) error {
original := *contest
var form ContestForm
if err := c.Bind(&form); err != nil {
return err
return httperr.BindFail(err)
}
form.Bind(contest)
if err := contest.Write(g.db); err != nil {
Expand All @@ -133,7 +134,7 @@ func (g *Group) ContestAddProblem(c echo.Context) error {
problem models.Problem
)
if err := c.Bind(&form); err != nil {
return err
return httperr.BindFail(err)
}
problem.ContestID = contest.ID
form.Bind(&problem)
Expand Down
5 changes: 3 additions & 2 deletions server/admin/contests.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
)
Expand All @@ -23,7 +24,7 @@ func (t Timestamp) String() string {
func (t *Timestamp) UnmarshalParam(src string) error {
ts, err := time.Parse(timeFormat, src)
*t = Timestamp(ts)
return err
return errors.WithStack(err)
}

// ContestsCtx is a context for rendering contests.
Expand Down Expand Up @@ -82,7 +83,7 @@ func (g *Group) contestsWithFormError(formError error, form ContestForm, c echo.
func (g *Group) ContestsPost(c echo.Context) error {
var form ContestForm
if err := c.Bind(&form); err != nil {
return errors.WithStack(err)
return httperr.BindFail(err)
}
var contest models.Contest
form.Bind(&contest)
Expand Down
5 changes: 3 additions & 2 deletions server/admin/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"git.nkagami.me/natsukagami/kjudge/db"
"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
)
Expand All @@ -18,11 +19,11 @@ func getFile(db db.DBContext, c echo.Context) (*models.File, error) {
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("File not found: %s", idStr)
}
file, err := models.GetFile(db, id)
if errors.Is(err, sql.ErrNoRows) {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("File not found: %d", id)
} else if err != nil {
return nil, err
}
Expand Down
11 changes: 6 additions & 5 deletions server/admin/problem.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strconv"

"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
)
Expand All @@ -32,7 +33,7 @@ func (o *OptionalInt64) UnmarshalParam(src string) error {
}
n, err := strconv.Atoi(src)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "expected a number, number not given")
return httperr.BadRequestf("expected a number, number not given")
}
o.Valid = true
o.Int64 = int64(n)
Expand Down Expand Up @@ -76,11 +77,11 @@ func (g *Group) getProblem(c echo.Context) (*ProblemCtx, error) {
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("Problem not found: %v", idStr)
}
problem, err := models.GetProblem(g.db, id)
if errors.Is(err, sql.ErrNoRows) {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("Problem not found: %v", idStr)
} else if err != nil {
return nil, err
}
Expand Down Expand Up @@ -197,7 +198,7 @@ func (g *Group) ProblemAddFile(c echo.Context) error {
makePublic := c.FormValue("public") == "true"
form, err := c.MultipartForm()
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BindFail(err)
}
var files []*models.File
for _, file := range form.File["file"] {
Expand All @@ -221,7 +222,7 @@ func (g *Group) ProblemAddFile(c echo.Context) error {
files[0].Filename = rename
}
if err := ctx.Problem.WriteFiles(g.db, files); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BadRequestf("cannot write files: %v", err)
}
return c.Redirect(http.StatusSeeOther, fmt.Sprintf("/admin/problems/%d#files", ctx.Problem.ID))
}
Expand Down
8 changes: 4 additions & 4 deletions server/admin/rejudge.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package admin

import (
"fmt"
"net/http"
"strconv"
"strings"

"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
)
Expand All @@ -19,7 +19,7 @@ func (g *Group) RejudgePost(c echo.Context) error {
for _, i := range idStr {
v, err := strconv.Atoi(i)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("id `%s`: %v", i, err.Error()))
return httperr.BadRequestf("submission id `%s`: %v", i, err)
}
id = append(id, v)
}
Expand All @@ -37,10 +37,10 @@ func (g *Group) RejudgePost(c echo.Context) error {
case "compile":
err = models.RejudgeCompile(tx, id...)
default:
err = echo.NewHTTPError(http.StatusBadRequest, "Invalid rejudge stage")
err = httperr.BadRequestf("Invalid rejudge stage: %s", stage)
}
if err != nil {
return err
return httperr.BadRequestf("Cannot rejudge: %v", err)
}
if err := tx.Commit(); err != nil {
return errors.WithStack(err)
Expand Down
7 changes: 4 additions & 3 deletions server/admin/submission.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"git.nkagami.me/natsukagami/kjudge/db"
"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"git.nkagami.me/natsukagami/kjudge/worker"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
Expand All @@ -34,11 +35,11 @@ func getSubmissionCtx(db db.DBContext, c echo.Context) (*SubmissionCtx, error) {
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("Submission not found: %v", idStr)
}
sub, err := models.GetSubmission(db, id)
if errors.Is(err, sql.ErrNoRows) {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("Submission not found: %v", idStr)
} else if err != nil {
return nil, err
}
Expand Down Expand Up @@ -93,7 +94,7 @@ func (g *Group) SubmissionBinaryGet(c echo.Context) error {
http.ServeContent(c.Response(), c.Request(), fmt.Sprintf("compiled_s%d", ctx.Submission.ID), ctx.Submission.SubmittedAt, bytes.NewReader(ctx.Submission.CompiledSource))
return nil
} else {
return echo.NewHTTPError(http.StatusBadRequest, "Compiled binary not available")
return httperr.BadRequestf("Compiled binary not available")
}
}

Expand Down
5 changes: 3 additions & 2 deletions server/admin/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"git.nkagami.me/natsukagami/kjudge/db"
"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
)
Expand All @@ -16,11 +17,11 @@ func getTest(db db.DBContext, c echo.Context) (*models.Test, error) {
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return nil, echo.ErrNotFound
return nil, httperr.BadRequestf("Test not found: %v", idStr)
}
test, err := models.GetTest(db, id)
if errors.Is(err, sql.ErrNoRows) {
return nil, echo.ErrNotFound
return nil, httperr.BadRequestf("Test not found: %v", idStr)
} else if err != nil {
return nil, err
}
Expand Down
23 changes: 12 additions & 11 deletions server/admin/test_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"git.nkagami.me/natsukagami/kjudge/db"
"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"git.nkagami.me/natsukagami/kjudge/tests"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
Expand All @@ -20,11 +21,11 @@ func getTestGroup(db db.DBContext, c echo.Context) (*models.TestGroup, error) {
idStr := c.Param("id")
id, err := strconv.Atoi(idStr)
if err != nil {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("Test group not found: %v", idStr)
}
tg, err := models.GetTestGroup(db, id)
if errors.Is(err, sql.ErrNoRows) {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("Test group not found: %v", idStr)
} else if err != nil {
return nil, err
}
Expand All @@ -46,7 +47,7 @@ func (g *Group) TestGroupUploadSingle(c echo.Context) error {
name := c.FormValue("name")
mp, err := c.MultipartForm()
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BindFail(err)
}
input, err := readFromForm("input", mp)
if err != nil {
Expand All @@ -64,7 +65,7 @@ func (g *Group) TestGroupUploadSingle(c echo.Context) error {
Output: output,
}
if err := test.Write(tx); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BadRequestf("Cannot write test: %v", err)
}
if err := tx.Commit(); err != nil {
return errors.WithStack(err)
Expand All @@ -87,18 +88,18 @@ func (g *Group) TestGroupUploadMultiple(c echo.Context) error {
override := c.FormValue("override") == "true"
mp, err := c.MultipartForm()
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BindFail(err)
}
file, err := readFromForm("file", mp)
if err != nil {
return err
}
tests, err := tests.Unpack(bytes.NewReader(file), int64(len(file)), c.FormValue("input"), c.FormValue("output"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BadRequestf("cannot unpack tests: %v", err)
}
if err := tg.WriteTests(tx, tests, override); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BadRequestf("Cannot write tests: %v", err)
}
if err := tx.Commit(); err != nil {
return err
Expand All @@ -114,11 +115,11 @@ func (g *Group) TestGroupEdit(c echo.Context) error {
}
var form TestGroupForm
if err := c.Bind(&form); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BindFail(err)
}
form.Bind(tg)
if err := tg.Write(g.db); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BadRequestf("Cannot update test group: %v", err)
}
return c.Redirect(http.StatusSeeOther, fmt.Sprintf("/admin/problems/%d", tg.ProblemID))
}
Expand All @@ -138,10 +139,10 @@ func (g *Group) TestGroupDelete(c echo.Context) error {
func readFromForm(name string, form *multipart.Form) ([]byte, error) {
file, ok := form.File[name]
if !ok {
return nil, echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("file %s not found", name))
return nil, httperr.BadRequestf("file %s not found", name)
}
if len(file) != 1 {
return nil, echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("file %s: expected one file, got %d", name, len(file)))
return nil, httperr.BadRequestf("file %s: expected one file, got %d", name, len(file))
}
f, err := file[0].Open()
if err != nil {
Expand Down
11 changes: 6 additions & 5 deletions server/admin/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"git.nkagami.me/natsukagami/kjudge/db"
"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"github.com/labstack/echo/v4"
"github.com/pkg/errors"
)
Expand All @@ -26,7 +27,7 @@ func getUser(db db.DBContext, c echo.Context) (*UserCtx, error) {
id := c.Param("id")
u, err := models.GetUser(db, id)
if errors.Is(err, sql.ErrNoRows) {
return nil, echo.ErrNotFound
return nil, httperr.NotFoundf("User not found: %v", id)
} else if err != nil {
return nil, err
}
Expand Down Expand Up @@ -78,7 +79,7 @@ func (g *Group) UserGet(c echo.Context) error {
func (g *Group) UserEdit(c echo.Context) error {
tx, err := g.db.Beginx()
if err != nil {
return err
return errors.WithStack(err)
}
defer tx.Rollback()
ctx, err := getUser(tx, c)
Expand All @@ -88,11 +89,11 @@ func (g *Group) UserEdit(c echo.Context) error {
nw := *ctx.User
var form UserForm
if err := c.Bind(&form); err != nil {
return err
return httperr.BindFail(err)
}
form.IsUpdate = true
if form.ID != nw.ID {
return echo.NewHTTPError(http.StatusBadRequest, "cannot change user id")
return httperr.BadRequestf("cannot change user id")
}
if err := form.Bind(&nw); err != nil {
ctx.EditForm = &form
Expand All @@ -107,7 +108,7 @@ func (g *Group) UserEdit(c echo.Context) error {
}

if err := tx.Commit(); err != nil {
return err
return errors.WithStack(err)
}

return c.Redirect(http.StatusSeeOther, fmt.Sprintf("/admin/users/%s", nw.ID))
Expand Down
3 changes: 2 additions & 1 deletion server/admin/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"git.nkagami.me/natsukagami/kjudge/db"
"git.nkagami.me/natsukagami/kjudge/models"
"git.nkagami.me/natsukagami/kjudge/server/auth"
"git.nkagami.me/natsukagami/kjudge/server/httperr"
"github.com/labstack/echo/v4"
)

Expand Down Expand Up @@ -74,7 +75,7 @@ func (g *Group) UsersGet(c echo.Context) error {
func (g *Group) UsersAdd(c echo.Context) error {
var form UserForm
if err := c.Bind(&form); err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err.Error())
return httperr.BindFail(err)
}
var u models.User
if err := form.Bind(&u); err != nil {
Expand Down
Loading

0 comments on commit 7ada7ee

Please sign in to comment.