Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ref: move httpapi.Reponse into codersdk#2954

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
sreya merged 6 commits intomainfromjon/refactorcodersdk
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes fromall 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
4 changes: 2 additions & 2 deletionscoderd/coderd.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -134,7 +134,7 @@ func New(options *Options) *API {

r.Route("/api/v2", func(r chi.Router) {
r.NotFound(func(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(rw, http.StatusNotFound,httpapi.Response{
httpapi.Write(rw, http.StatusNotFound,codersdk.Response{
Message: "Route not found.",
})
})
Expand All@@ -144,7 +144,7 @@ func New(options *Options) *API {
debugLogRequest(api.Logger),
)
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
httpapi.Write(w, http.StatusOK,httpapi.Response{
httpapi.Write(w, http.StatusOK,codersdk.Response{
//nolint:gocritic
Message: "👋",
})
Expand Down
3 changes: 2 additions & 1 deletioncoderd/csp.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,6 +5,7 @@ import (
"net/http"

"github.com/coder/coder/coderd/httpapi"
"github.com/coder/coder/codersdk"

"cdr.dev/slog"
)
Expand All@@ -22,7 +23,7 @@ func (api *API) logReportCSPViolations(rw http.ResponseWriter, r *http.Request)
err := dec.Decode(&v)
if err != nil {
api.Logger.Warn(ctx, "csp violation", slog.Error(err))
httpapi.Write(rw, http.StatusBadRequest,httpapi.Response{
httpapi.Write(rw, http.StatusBadRequest,codersdk.Response{
Message: "Failed to read body, invalid json.",
Detail: err.Error(),
})
Expand Down
10 changes: 5 additions & 5 deletionscoderd/files.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,7 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
switch contentType {
case "application/x-tar":
default:
httpapi.Write(rw, http.StatusBadRequest,httpapi.Response{
httpapi.Write(rw, http.StatusBadRequest,codersdk.Response{
Message: fmt.Sprintf("Unsupported content type header %q.", contentType),
})
return
Expand All@@ -41,7 +41,7 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(rw, r.Body, 10*(10<<20))
data, err := io.ReadAll(r.Body)
if err != nil {
httpapi.Write(rw, http.StatusBadRequest,httpapi.Response{
httpapi.Write(rw, http.StatusBadRequest,codersdk.Response{
Message: "Failed to read file from request.",
Detail: err.Error(),
})
Expand All@@ -65,7 +65,7 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
Data: data,
})
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error saving file.",
Detail: err.Error(),
})
Expand All@@ -80,7 +80,7 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
func (api *API) fileByHash(rw http.ResponseWriter, r *http.Request) {
hash := chi.URLParam(r, "hash")
if hash == "" {
httpapi.Write(rw, http.StatusBadRequest,httpapi.Response{
httpapi.Write(rw, http.StatusBadRequest,codersdk.Response{
Message: "File hash must be provided in url.",
})
return
Expand All@@ -91,7 +91,7 @@ func (api *API) fileByHash(rw http.ResponseWriter, r *http.Request) {
return
}
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error fetching file.",
Detail: err.Error(),
})
Expand Down
16 changes: 8 additions & 8 deletionscoderd/gitsshkey.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) {

privateKey, publicKey, err := gitsshkey.Generate(api.SSHKeygenAlgorithm)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error generating a new SSH keypair.",
Detail: err.Error(),
})
Expand All@@ -35,7 +35,7 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) {
PublicKey: publicKey,
})
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error updating user's git SSH key.",
Detail: err.Error(),
})
Expand All@@ -44,7 +44,7 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) {

newKey, err := api.Database.GetGitSSHKey(r.Context(), user.ID)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error fetching user's git SSH key.",
Detail: err.Error(),
})
Expand All@@ -70,7 +70,7 @@ func (api *API) gitSSHKey(rw http.ResponseWriter, r *http.Request) {

gitSSHKey, err := api.Database.GetGitSSHKey(r.Context(), user.ID)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error fetching user's SSH key.",
Detail: err.Error(),
})
Expand All@@ -90,7 +90,7 @@ func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) {
agent := httpmw.WorkspaceAgent(r)
resource, err := api.Database.GetWorkspaceResourceByID(r.Context(), agent.ResourceID)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error fetching workspace resource.",
Detail: err.Error(),
})
Expand All@@ -99,7 +99,7 @@ func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) {

job, err := api.Database.GetWorkspaceBuildByJobID(r.Context(), resource.JobID)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error fetching workspace build.",
Detail: err.Error(),
})
Expand All@@ -108,7 +108,7 @@ func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) {

workspace, err := api.Database.GetWorkspaceByID(r.Context(), job.WorkspaceID)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error fetching workspace.",
Detail: err.Error(),
})
Expand All@@ -117,7 +117,7 @@ func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) {

gitSSHKey, err := api.Database.GetGitSSHKey(r.Context(), workspace.OwnerID)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError,httpapi.Response{
httpapi.Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error fetching git SSH key.",
Detail: err.Error(),
})
Expand Down
42 changes: 9 additions & 33 deletionscoderd/httpapi/httpapi.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,8 @@ import (
"strings"

"github.com/go-playground/validator/v10"

"github.com/coder/coder/codersdk"
)

var (
Expand DownExpand Up@@ -50,42 +52,16 @@ func init() {
}
}

// Response represents a generic HTTP response.
type Response struct {
// Message is an actionable message that depicts actions the request took.
// These messages should be fully formed sentences with proper punctuation.
// Examples:
// - "A user has been created."
// - "Failed to create a user."
Message string `json:"message"`
// Detail is a debug message that provides further insight into why the
// action failed. This information can be technical and a regular golang
// err.Error() text.
// - "database: too many open connections"
// - "stat: too many open files"
Detail string `json:"detail,omitempty"`
// Validations are form field-specific friendly error messages. They will be
// shown on a form field in the UI. These can also be used to add additional
// context if there is a set of errors in the primary 'Message'.
Validations []Error `json:"validations,omitempty"`
}

// Error represents a scoped error to a user input.
type Error struct {
Field string `json:"field" validate:"required"`
Detail string `json:"detail" validate:"required"`
}

// ResourceNotFound is intentionally vague. All 404 responses should be identical
// to prevent leaking existence of resources.
func ResourceNotFound(rw http.ResponseWriter) {
Write(rw, http.StatusNotFound, Response{
Write(rw, http.StatusNotFound,codersdk.Response{
Message: "Resource not found or you do not have access to this resource",
})
}

func Forbidden(rw http.ResponseWriter) {
Write(rw, http.StatusForbidden, Response{
Write(rw, http.StatusForbidden,codersdk.Response{
Message: "Forbidden.",
})
}
Expand DownExpand Up@@ -114,7 +90,7 @@ func Write(rw http.ResponseWriter, status int, response interface{}) {
func Read(rw http.ResponseWriter, r *http.Request, value interface{}) bool {
err := json.NewDecoder(r.Body).Decode(value)
if err != nil {
Write(rw, http.StatusBadRequest, Response{
Write(rw, http.StatusBadRequest,codersdk.Response{
Message: "Request body must be valid JSON.",
Detail: err.Error(),
})
Expand All@@ -123,21 +99,21 @@ func Read(rw http.ResponseWriter, r *http.Request, value interface{}) bool {
err = validate.Struct(value)
var validationErrors validator.ValidationErrors
if errors.As(err, &validationErrors) {
apiErrors := make([]Error, 0, len(validationErrors))
apiErrors := make([]codersdk.ValidationError, 0, len(validationErrors))
for _, validationError := range validationErrors {
apiErrors = append(apiErrors,Error{
apiErrors = append(apiErrors,codersdk.ValidationError{
Field: validationError.Field(),
Detail: fmt.Sprintf("Validation failed for tag %q with value: \"%v\"", validationError.Tag(), validationError.Value()),
})
}
Write(rw, http.StatusBadRequest, Response{
Write(rw, http.StatusBadRequest,codersdk.Response{
Message: "Validation failed.",
Validations: apiErrors,
})
return false
}
if err != nil {
Write(rw, http.StatusInternalServerError, Response{
Write(rw, http.StatusInternalServerError,codersdk.Response{
Message: "Internal error validating request body payload.",
Detail: err.Error(),
})
Expand Down
5 changes: 3 additions & 2 deletionscoderd/httpapi/httpapi_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,14 +12,15 @@ import (
"github.com/stretchr/testify/require"

"github.com/coder/coder/coderd/httpapi"
"github.com/coder/coder/codersdk"
)

func TestWrite(t *testing.T) {
t.Parallel()
t.Run("NoErrors", func(t *testing.T) {
t.Parallel()
rw := httptest.NewRecorder()
httpapi.Write(rw, http.StatusOK,httpapi.Response{
httpapi.Write(rw, http.StatusOK,codersdk.Response{
Message: "Wow.",
})
var m map[string]interface{}
Expand DownExpand Up@@ -71,7 +72,7 @@ func TestRead(t *testing.T) {

var validate toValidate
require.False(t, httpapi.Read(rw, r, &validate))
var vhttpapi.Response
var vcodersdk.Response
err := json.NewDecoder(rw.Body).Decode(&v)
require.NoError(t, err)
require.Len(t, v.Validations, 1)
Expand Down
14 changes: 8 additions & 6 deletionscoderd/httpapi/queryparams.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,6 +8,8 @@ import (

"github.com/google/uuid"

"github.com/coder/coder/codersdk"

"golang.org/x/xerrors"
)

Expand All@@ -17,19 +19,19 @@ import (
type QueryParamParser struct {
// Errors is the set of errors to return via the API. If the length
// of this set is 0, there are no errors!.
Errors []Error
Errors []codersdk.ValidationError
}

func NewQueryParamParser() *QueryParamParser {
return &QueryParamParser{
Errors: []Error{},
Errors: []codersdk.ValidationError{},
}
}

func (p *QueryParamParser) Int(vals url.Values, def int, queryParam string) int {
v, err := parseQueryParam(vals, strconv.Atoi, def, queryParam)
if err != nil {
p.Errors = append(p.Errors,Error{
p.Errors = append(p.Errors,codersdk.ValidationError{
Field: queryParam,
Detail: fmt.Sprintf("Query param %q must be a valid integer (%s)", queryParam, err.Error()),
})
Expand All@@ -47,7 +49,7 @@ func (p *QueryParamParser) UUIDorMe(vals url.Values, def uuid.UUID, me uuid.UUID
func (p *QueryParamParser) UUID(vals url.Values, def uuid.UUID, queryParam string) uuid.UUID {
v, err := parseQueryParam(vals, uuid.Parse, def, queryParam)
if err != nil {
p.Errors = append(p.Errors,Error{
p.Errors = append(p.Errors,codersdk.ValidationError{
Field: queryParam,
Detail: fmt.Sprintf("Query param %q must be a valid uuid", queryParam),
})
Expand DownExpand Up@@ -75,7 +77,7 @@ func (p *QueryParamParser) UUIDs(vals url.Values, def []uuid.UUID, queryParam st
return ids, nil
}, def, queryParam)
if err != nil {
p.Errors = append(p.Errors,Error{
p.Errors = append(p.Errors,codersdk.ValidationError{
Field: queryParam,
Detail: fmt.Sprintf("Query param %q has invalid uuids: %q", queryParam, err.Error()),
})
Expand DownExpand Up@@ -105,7 +107,7 @@ func (*QueryParamParser) Strings(vals url.Values, def []string, queryParam strin
func ParseCustom[T any](parser *QueryParamParser, vals url.Values, def T, queryParam string, parseFunc func(v string) (T, error)) T {
v, err := parseQueryParam(vals, parseFunc, def, queryParam)
if err != nil {
parser.Errors = append(parser.Errors,Error{
parser.Errors = append(parser.Errors,codersdk.ValidationError{
Field: queryParam,
Detail: fmt.Sprintf("Query param %q has invalid value: %s", queryParam, err.Error()),
})
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp