Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions problem_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ type ProblemConfig struct {
func NewProblemConfig() ProblemConfig {
return ProblemConfig{
ErrorTypePaths: map[string]string{
"validation_error": "/errors/validation-error",
"not_found_error": "/errors/not-found",
"server_error": "/errors/server-error",
"bad_request_error": "/errors/bad-request",
"validation_error": "/errors/validation-error",
"not_found_error": "/errors/not-found",
"server_error": "/errors/server-error",
"bad_request_error": "/errors/bad-request",
"unauthorized_error": "/errors/unauthorized",
"forbidden_error": "/errors/forbidden",
"conflict_error": "/errors/conflict",
"unprocessable_error": "/errors/unprocessable-entity",
},
}
}
Expand Down
65 changes: 65 additions & 0 deletions problem_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,46 @@ func ProblemNotFound(detail string) *ProblemBuilder {
Detail(detail)
}

// ProblemUnauthorized returns an unauthorized problem builder.
func ProblemUnauthorized(detail string) *ProblemBuilder {
return Problem(http.StatusUnauthorized).
Type(GetProblemTypeURL("unauthorized_error")).
Title("Unauthorized").
Detail(detail)
}

// ProblemForbidden returns a forbidden problem builder.
func ProblemForbidden(detail string) *ProblemBuilder {
return Problem(http.StatusForbidden).
Type(GetProblemTypeURL("forbidden_error")).
Title("Forbidden").
Detail(detail)
}

// ProblemConflict returns a conflict problem builder.
func ProblemConflict(detail string) *ProblemBuilder {
return Problem(http.StatusConflict).
Type(GetProblemTypeURL("conflict_error")).
Title("Conflict").
Detail(detail)
}

// ProblemUnprocessable returns an unprocessable entity problem builder.
func ProblemUnprocessable(detail string) *ProblemBuilder {
return Problem(http.StatusUnprocessableEntity).
Type(GetProblemTypeURL("unprocessable_error")).
Title("Unprocessable Entity").
Detail(detail)
}

// ProblemInternal returns an internal server error problem builder.
func ProblemInternal(detail string) *ProblemBuilder {
return Problem(http.StatusInternalServerError).
Type(GetProblemTypeURL("server_error")).
Title("Internal Server Error").
Detail(detail)
}

// NewBadRequestProblem returns a ready-to-use bad request problem.
func NewBadRequestProblem(detail string) *ProblemDetails {
return ProblemBadRequest(detail).Build()
Expand All @@ -27,3 +67,28 @@ func NewBadRequestProblem(detail string) *ProblemDetails {
func NewNotFoundProblem(detail string) *ProblemDetails {
return ProblemNotFound(detail).Build()
}

// NewUnauthorizedProblem returns a ready-to-use unauthorized problem.
func NewUnauthorizedProblem(detail string) *ProblemDetails {
return ProblemUnauthorized(detail).Build()
}

// NewForbiddenProblem returns a ready-to-use forbidden problem.
func NewForbiddenProblem(detail string) *ProblemDetails {
return ProblemForbidden(detail).Build()
}

// NewConflictProblem returns a ready-to-use conflict problem.
func NewConflictProblem(detail string) *ProblemDetails {
return ProblemConflict(detail).Build()
}

// NewUnprocessableProblem returns a ready-to-use unprocessable entity problem.
func NewUnprocessableProblem(detail string) *ProblemDetails {
return ProblemUnprocessable(detail).Build()
}

// NewInternalProblem returns a ready-to-use internal server error problem.
func NewInternalProblem(detail string) *ProblemDetails {
return ProblemInternal(detail).Build()
}
40 changes: 40 additions & 0 deletions problem_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,46 @@ func TestProblemBuilderHelpers(t *testing.T) {
}
}

func TestStatusProblemHelpers(t *testing.T) {
t.Parallel()

tests := []struct {
name string
builder func(string) *ProblemBuilder
direct func(string) *ProblemDetails
status int
title string
errType string
}{
{"unauthorized", ProblemUnauthorized, NewUnauthorizedProblem, http.StatusUnauthorized, "Unauthorized", "unauthorized_error"},
{"forbidden", ProblemForbidden, NewForbiddenProblem, http.StatusForbidden, "Forbidden", "forbidden_error"},
{"conflict", ProblemConflict, NewConflictProblem, http.StatusConflict, "Conflict", "conflict_error"},
{"unprocessable", ProblemUnprocessable, NewUnprocessableProblem, http.StatusUnprocessableEntity, "Unprocessable Entity", "unprocessable_error"},
{"internal", ProblemInternal, NewInternalProblem, http.StatusInternalServerError, "Internal Server Error", "server_error"},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

for _, got := range []*ProblemDetails{tt.builder("some detail").Build(), tt.direct("some detail")} {
if got.Status != tt.status {
t.Errorf("status = %d, want %d", got.Status, tt.status)
}
if got.Title != tt.title {
t.Errorf("title = %q, want %q", got.Title, tt.title)
}
if got.Detail != "some detail" {
t.Errorf("detail = %q", got.Detail)
}
if want := GetProblemTypeURL(tt.errType); got.Type != want || want == BlankURL {
t.Errorf("type = %q, want %q", got.Type, want)
}
}
})
}
}

func TestDirectProblemHelpers(t *testing.T) {
t.Parallel()

Expand Down
Loading