Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit af401e3

Browse files
authored
chore: Linter rule for properly formatted api errors (#2123)
* chore: Linter rule for properly formatted api errors * Add omitempty to 'Detail' field
1 parent 3f1e885 commit af401e3

37 files changed

+351
-302
lines changed

coderd/coderd.go

+1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ func New(options *Options) *API {
123123
)
124124
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
125125
httpapi.Write(w, http.StatusOK, httpapi.Response{
126+
//nolint:gocritic
126127
Message: "👋",
127128
})
128129
})

coderd/csp.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func (api *API) logReportCSPViolations(rw http.ResponseWriter, r *http.Request)
2323
if err != nil {
2424
api.Logger.Warn(ctx, "csp violation", slog.Error(err))
2525
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
26-
Message: "Failed to read body, invalid json",
26+
Message: "Failed to read body, invalid json.",
2727
Detail: err.Error(),
2828
})
2929
return

coderd/files.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
3232
case "application/x-tar":
3333
default:
3434
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
35-
Message: fmt.Sprintf("Unsupported content type header %q", contentType),
35+
Message: fmt.Sprintf("Unsupported content type header %q.", contentType),
3636
})
3737
return
3838
}
@@ -41,7 +41,7 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
4141
data, err := io.ReadAll(r.Body)
4242
if err != nil {
4343
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
44-
Message: "Failed to read file from request",
44+
Message: "Failed to read file from request.",
4545
Detail: err.Error(),
4646
})
4747
return
@@ -65,7 +65,7 @@ func (api *API) postFile(rw http.ResponseWriter, r *http.Request) {
6565
})
6666
if err != nil {
6767
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
68-
Message: "Internal error saving file",
68+
Message: "Internal error saving file.",
6969
Detail: err.Error(),
7070
})
7171
return
@@ -80,7 +80,7 @@ func (api *API) fileByHash(rw http.ResponseWriter, r *http.Request) {
8080
hash := chi.URLParam(r, "hash")
8181
if hash == "" {
8282
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
83-
Message: "File hash must be provided in url",
83+
Message: "File hash must be provided in url.",
8484
})
8585
return
8686
}
@@ -91,7 +91,7 @@ func (api *API) fileByHash(rw http.ResponseWriter, r *http.Request) {
9191
}
9292
if err != nil {
9393
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
94-
Message: "Internal error fetching file",
94+
Message: "Internal error fetching file.",
9595
Detail: err.Error(),
9696
})
9797
return

coderd/gitsshkey.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) {
2121
privateKey, publicKey, err := gitsshkey.Generate(api.SSHKeygenAlgorithm)
2222
if err != nil {
2323
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
24-
Message: "Internal error generating a new SSH keypair",
24+
Message: "Internal error generating a new SSH keypair.",
2525
Detail: err.Error(),
2626
})
2727
return
@@ -35,7 +35,7 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) {
3535
})
3636
if err != nil {
3737
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
38-
Message: "Internal error updating user's git SSH key",
38+
Message: "Internal error updating user's git SSH key.",
3939
Detail: err.Error(),
4040
})
4141
return
@@ -44,7 +44,7 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) {
4444
newKey, err := api.Database.GetGitSSHKey(r.Context(), user.ID)
4545
if err != nil {
4646
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
47-
Message: "Internal error fetching user's git SSH key",
47+
Message: "Internal error fetching user's git SSH key.",
4848
Detail: err.Error(),
4949
})
5050
return
@@ -69,7 +69,7 @@ func (api *API) gitSSHKey(rw http.ResponseWriter, r *http.Request) {
6969
gitSSHKey, err := api.Database.GetGitSSHKey(r.Context(), user.ID)
7070
if err != nil {
7171
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
72-
Message: "Internal error fetching user's SSH key",
72+
Message: "Internal error fetching user's SSH key.",
7373
Detail: err.Error(),
7474
})
7575
return
@@ -89,7 +89,7 @@ func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) {
8989
resource, err := api.Database.GetWorkspaceResourceByID(r.Context(), agent.ResourceID)
9090
if err != nil {
9191
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
92-
Message: "Internal error fetching workspace resource",
92+
Message: "Internal error fetching workspace resource.",
9393
Detail: err.Error(),
9494
})
9595
return
@@ -98,7 +98,7 @@ func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) {
9898
job, err := api.Database.GetWorkspaceBuildByJobID(r.Context(), resource.JobID)
9999
if err != nil {
100100
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
101-
Message: "Internal error fetching workspace build",
101+
Message: "Internal error fetching workspace build.",
102102
Detail: err.Error(),
103103
})
104104
return
@@ -107,7 +107,7 @@ func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) {
107107
workspace, err := api.Database.GetWorkspaceByID(r.Context(), job.WorkspaceID)
108108
if err != nil {
109109
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
110-
Message: "Internal error fetching workspace",
110+
Message: "Internal error fetching workspace.",
111111
Detail: err.Error(),
112112
})
113113
return
@@ -116,7 +116,7 @@ func (api *API) agentGitSSHKey(rw http.ResponseWriter, r *http.Request) {
116116
gitSSHKey, err := api.Database.GetGitSSHKey(r.Context(), workspace.OwnerID)
117117
if err != nil {
118118
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
119-
Message: "Internal error fetching git SSH key",
119+
Message: "Internal error fetching git SSH key.",
120120
Detail: err.Error(),
121121
})
122122
return

coderd/httpapi/httpapi.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ type Response struct {
6363
// err.Error() text.
6464
// - "database: too many open connections"
6565
// - "stat: too many open files"
66-
Detail string `json:"detail"`
66+
Detail string `json:"detail,omitempty"`
6767
// Validations are form field-specific friendly error messages. They will be
6868
// shown on a form field in the UI. These can also be used to add additional
6969
// context if there is a set of errors in the primary 'Message'.
@@ -78,7 +78,7 @@ type Error struct {
7878

7979
func Forbidden(rw http.ResponseWriter) {
8080
Write(rw, http.StatusForbidden, Response{
81-
Message: "Forbidden",
81+
Message: "Forbidden.",
8282
})
8383
}
8484

@@ -107,7 +107,7 @@ func Read(rw http.ResponseWriter, r *http.Request, value interface{}) bool {
107107
err := json.NewDecoder(r.Body).Decode(value)
108108
if err != nil {
109109
Write(rw, http.StatusBadRequest, Response{
110-
Message: "Request body must be valid JSON",
110+
Message: "Request body must be valid JSON.",
111111
Detail: err.Error(),
112112
})
113113
return false
@@ -123,14 +123,14 @@ func Read(rw http.ResponseWriter, r *http.Request, value interface{}) bool {
123123
})
124124
}
125125
Write(rw, http.StatusBadRequest, Response{
126-
Message: "Validation failed",
126+
Message: "Validation failed.",
127127
Validations: apiErrors,
128128
})
129129
return false
130130
}
131131
if err != nil {
132132
Write(rw, http.StatusInternalServerError, Response{
133-
Message: "Internal error validating request body payload",
133+
Message: "Internal error validating request body payload.",
134134
Detail: err.Error(),
135135
})
136136
return false

coderd/httpapi/httpapi_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func TestWrite(t *testing.T) {
2020
t.Parallel()
2121
rw := httptest.NewRecorder()
2222
httpapi.Write(rw, http.StatusOK, httpapi.Response{
23-
Message: "wow",
23+
Message: "Wow.",
2424
})
2525
var m map[string]interface{}
2626
err := json.NewDecoder(rw.Body).Decode(&m)

coderd/httpmw/apikey.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs) func(http.Handler) h
6565
}
6666
if cookieValue == "" {
6767
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
68-
Message: fmt.Sprintf("Cookie %q or query parameter must be provided", SessionTokenKey),
68+
Message: fmt.Sprintf("Cookie %q or query parameter must be provided.", SessionTokenKey),
6969
})
7070
return
7171
}
7272
parts := strings.Split(cookieValue, "-")
7373
// APIKeys are formatted: ID-SECRET
7474
if len(parts) != 2 {
7575
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
76-
Message: fmt.Sprintf("Invalid %q cookie API key format", SessionTokenKey),
76+
Message: fmt.Sprintf("Invalid %q cookie API key format.", SessionTokenKey),
7777
})
7878
return
7979
}
@@ -82,26 +82,26 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs) func(http.Handler) h
8282
// Ensuring key lengths are valid.
8383
if len(keyID) != 10 {
8484
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
85-
Message: fmt.Sprintf("Invalid %q cookie API key id", SessionTokenKey),
85+
Message: fmt.Sprintf("Invalid %q cookie API key id.", SessionTokenKey),
8686
})
8787
return
8888
}
8989
if len(keySecret) != 22 {
9090
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
91-
Message: fmt.Sprintf("Invalid %q cookie API key secret", SessionTokenKey),
91+
Message: fmt.Sprintf("Invalid %q cookie API key secret.", SessionTokenKey),
9292
})
9393
return
9494
}
9595
key, err := db.GetAPIKeyByID(r.Context(), keyID)
9696
if err != nil {
9797
if errors.Is(err, sql.ErrNoRows) {
9898
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
99-
Message: "API key is invalid",
99+
Message: "API key is invalid.",
100100
})
101101
return
102102
}
103103
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
104-
Message: "Internal error fetching API key by id",
104+
Message: "Internal error fetching API key by id.",
105105
Detail: err.Error(),
106106
})
107107
return
@@ -111,7 +111,7 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs) func(http.Handler) h
111111
// Checking to see if the secret is valid.
112112
if subtle.ConstantTimeCompare(key.HashedSecret, hashed[:]) != 1 {
113113
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
114-
Message: "API key secret is invalid",
114+
Message: "API key secret is invalid.",
115115
})
116116
return
117117
}
@@ -128,7 +128,7 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs) func(http.Handler) h
128128
oauthConfig = oauth.Github
129129
default:
130130
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
131-
Message: fmt.Sprintf("Unexpected authentication type %q", key.LoginType),
131+
Message: fmt.Sprintf("Unexpected authentication type %q.", key.LoginType),
132132
})
133133
return
134134
}
@@ -140,7 +140,7 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs) func(http.Handler) h
140140
}).Token()
141141
if err != nil {
142142
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
143-
Message: "Could not refresh expired Oauth token",
143+
Message: "Could not refresh expired Oauth token.",
144144
Detail: err.Error(),
145145
})
146146
return
@@ -156,7 +156,7 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs) func(http.Handler) h
156156
// Checking if the key is expired.
157157
if key.ExpiresAt.Before(now) {
158158
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
159-
Message: fmt.Sprintf("API key expired at %q", key.ExpiresAt.String()),
159+
Message: fmt.Sprintf("API key expired at %q.", key.ExpiresAt.String()),
160160
})
161161
return
162162
}
@@ -184,7 +184,7 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs) func(http.Handler) h
184184
})
185185
if err != nil {
186186
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
187-
Message: fmt.Sprintf("API key couldn't update: %s", err.Error()),
187+
Message: fmt.Sprintf("API key couldn't update: %s.", err.Error()),
188188
})
189189
return
190190
}
@@ -196,7 +196,7 @@ func ExtractAPIKey(db database.Store, oauth *OAuth2Configs) func(http.Handler) h
196196
roles, err := db.GetAuthorizationUserRoles(r.Context(), key.UserID)
197197
if err != nil {
198198
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
199-
Message: "Internal error fetching user's roles",
199+
Message: "Internal error fetching user's roles.",
200200
Detail: err.Error(),
201201
})
202202
return

coderd/httpmw/apikey_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestAPIKey(t *testing.T) {
3232
successHandler := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
3333
// Only called if the API key passes through the handler.
3434
httpapi.Write(rw, http.StatusOK, httpapi.Response{
35-
Message: "it worked!",
35+
Message: "It worked!",
3636
})
3737
})
3838

@@ -203,7 +203,7 @@ func TestAPIKey(t *testing.T) {
203203
// Checks that it exists on the context!
204204
_ = httpmw.APIKey(r)
205205
httpapi.Write(rw, http.StatusOK, httpapi.Response{
206-
Message: "it worked!",
206+
Message: "It worked!",
207207
})
208208
})).ServeHTTP(rw, r)
209209
res := rw.Result()
@@ -241,7 +241,7 @@ func TestAPIKey(t *testing.T) {
241241
// Checks that it exists on the context!
242242
_ = httpmw.APIKey(r)
243243
httpapi.Write(rw, http.StatusOK, httpapi.Response{
244-
Message: "it worked!",
244+
Message: "It worked!",
245245
})
246246
})).ServeHTTP(rw, r)
247247
res := rw.Result()

coderd/httpmw/httpmw.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func parseUUID(rw http.ResponseWriter, r *http.Request, param string) (uuid.UUID
1515
rawID := chi.URLParam(r, param)
1616
if rawID == "" {
1717
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
18-
Message: "Missing UUID in URL",
18+
Message: "Missing UUID in URL.",
1919
// Url params mean nothing to a user
2020
Detail: fmt.Sprintf("%q URL param missing", param),
2121
})
@@ -25,7 +25,7 @@ func parseUUID(rw http.ResponseWriter, r *http.Request, param string) (uuid.UUID
2525
parsed, err := uuid.Parse(rawID)
2626
if err != nil {
2727
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
28-
Message: fmt.Sprintf("Invalid UUID %q", param),
28+
Message: fmt.Sprintf("Invalid UUID %q.", param),
2929
Detail: err.Error(),
3030
})
3131
return uuid.UUID{}, false

coderd/httpmw/oauth2.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func ExtractOAuth2(config OAuth2Config) func(http.Handler) http.Handler {
6363
state, err := cryptorand.String(32)
6464
if err != nil {
6565
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
66-
Message: "Internal error generating state string",
66+
Message: "Internal error generating state string.",
6767
Detail: err.Error(),
6868
})
6969
return
@@ -92,21 +92,21 @@ func ExtractOAuth2(config OAuth2Config) func(http.Handler) http.Handler {
9292

9393
if state == "" {
9494
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
95-
Message: "State must be provided",
95+
Message: "State must be provided.",
9696
})
9797
return
9898
}
9999

100100
stateCookie, err := r.Cookie(oauth2StateCookieName)
101101
if err != nil {
102102
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
103-
Message: fmt.Sprintf("Cookie %q must be provided", oauth2StateCookieName),
103+
Message: fmt.Sprintf("Cookie %q must be provided.", oauth2StateCookieName),
104104
})
105105
return
106106
}
107107
if stateCookie.Value != state {
108108
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
109-
Message: "State mismatched",
109+
Message: "State mismatched.",
110110
})
111111
return
112112
}
@@ -120,7 +120,7 @@ func ExtractOAuth2(config OAuth2Config) func(http.Handler) http.Handler {
120120
oauthToken, err := config.Exchange(r.Context(), code)
121121
if err != nil {
122122
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
123-
Message: "Internal error exchanging Oauth code",
123+
Message: "Internal error exchanging Oauth code.",
124124
Detail: err.Error(),
125125
})
126126
return

0 commit comments

Comments
 (0)