mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: Linter rule for properly formatted api errors (#2123)
* chore: Linter rule for properly formatted api errors * Add omitempty to 'Detail' field
This commit is contained in:
+38
-37
@@ -46,7 +46,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
|
||||
showDeleted, err = strconv.ParseBool(deletedStr)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: fmt.Sprintf("Invalid boolean value %q for \"deleted\" query param", deletedStr),
|
||||
Message: fmt.Sprintf("Invalid boolean value %q for \"deleted\" query param.", deletedStr),
|
||||
Validations: []httpapi.Error{
|
||||
{Field: "deleted", Detail: "Must be a valid boolean"},
|
||||
},
|
||||
@@ -56,7 +56,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
if workspace.Deleted && !showDeleted {
|
||||
httpapi.Write(rw, http.StatusGone, httpapi.Response{
|
||||
Message: fmt.Sprintf("Workspace %q was deleted, you can view this workspace by specifying '?deleted=true' and trying again", workspace.ID.String()),
|
||||
Message: fmt.Sprintf("Workspace %q was deleted, you can view this workspace by specifying '?deleted=true' and trying again.", workspace.ID.String()),
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -64,7 +64,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
|
||||
build, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(r.Context(), workspace.ID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching workspace build",
|
||||
Message: "Internal error fetching workspace build.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -90,7 +90,7 @@ func (api *API) workspace(rw http.ResponseWriter, r *http.Request) {
|
||||
err = group.Wait()
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching resource",
|
||||
Message: "Internal error fetching resource.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -141,7 +141,7 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
|
||||
workspaces, err := api.Database.GetWorkspacesWithFilter(r.Context(), filter)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching workspaces",
|
||||
Message: "Internal error fetching workspaces.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -153,7 +153,8 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
|
||||
apiWorkspaces, err := convertWorkspaces(r.Context(), api.Database, workspaces)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("convert workspaces: %s", err),
|
||||
Message: "Internal error reading workspace.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -175,7 +176,7 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching workspace by name",
|
||||
Message: "Internal error fetching workspace by name.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -187,7 +188,7 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
|
||||
build, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(r.Context(), workspace.ID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching workspace build",
|
||||
Message: "Internal error fetching workspace build.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -195,7 +196,7 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), build.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching provisioner job",
|
||||
Message: "Internal error fetching provisioner job.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -203,7 +204,7 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request)
|
||||
template, err := api.Database.GetTemplateByID(r.Context(), workspace.TemplateID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching template",
|
||||
Message: "Internal error fetching template.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -229,7 +230,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
template, err := api.Database.GetTemplateByID(r.Context(), createWorkspace.TemplateID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: fmt.Sprintf("Template %q doesn't exist", createWorkspace.TemplateID.String()),
|
||||
Message: fmt.Sprintf("Template %q doesn't exist.", createWorkspace.TemplateID.String()),
|
||||
Validations: []httpapi.Error{{
|
||||
Field: "template_id",
|
||||
Detail: "template not found",
|
||||
@@ -239,7 +240,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching template",
|
||||
Message: "Internal error fetching template.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -247,7 +248,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
|
||||
if organization.ID != template.OrganizationID {
|
||||
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
|
||||
Message: fmt.Sprintf("Template is not in organization %q", organization.Name),
|
||||
Message: fmt.Sprintf("Template is not in organization %q.", organization.Name),
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -257,13 +258,13 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
|
||||
Message: "You aren't allowed to access templates in that organization",
|
||||
Message: "You aren't allowed to access templates in that organization.",
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching organization member",
|
||||
Message: "Internal error fetching organization member.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -272,7 +273,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
dbAutostartSchedule, err := validWorkspaceSchedule(createWorkspace.AutostartSchedule, time.Duration(template.MinAutostartInterval))
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: "Invalid Autostart Schedule",
|
||||
Message: "Invalid Autostart Schedule.",
|
||||
Validations: []httpapi.Error{{Field: "schedule", Detail: err.Error()}},
|
||||
})
|
||||
return
|
||||
@@ -281,7 +282,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
dbTTL, err := validWorkspaceTTLMillis(createWorkspace.TTLMillis, time.Duration(template.MaxTtl))
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: "Invalid Workspace TTL",
|
||||
Message: "Invalid Workspace TTL.",
|
||||
Validations: []httpapi.Error{{Field: "ttl_ms", Detail: err.Error()}},
|
||||
})
|
||||
return
|
||||
@@ -301,14 +302,14 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
template, err := api.Database.GetTemplateByID(r.Context(), workspace.TemplateID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("Find template for conflicting workspace name %q", createWorkspace.Name),
|
||||
Message: fmt.Sprintf("Find template for conflicting workspace name %q.", createWorkspace.Name),
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
// The template is fetched for clarity to the user on where the conflicting name may be.
|
||||
httpapi.Write(rw, http.StatusConflict, httpapi.Response{
|
||||
Message: fmt.Sprintf("Workspace %q already exists in the %q template", createWorkspace.Name, template.Name),
|
||||
Message: fmt.Sprintf("Workspace %q already exists in the %q template.", createWorkspace.Name, template.Name),
|
||||
Validations: []httpapi.Error{{
|
||||
Field: "name",
|
||||
Detail: "this value is already in use and should be unique",
|
||||
@@ -318,7 +319,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
}
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("Internal error fetching workspace by name %q", createWorkspace.Name),
|
||||
Message: fmt.Sprintf("Internal error fetching workspace by name %q.", createWorkspace.Name),
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -327,7 +328,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
templateVersion, err := api.Database.GetTemplateVersionByID(r.Context(), template.ActiveVersionID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching template version",
|
||||
Message: "Internal error fetching template version.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -335,7 +336,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
templateVersionJob, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching template version job",
|
||||
Message: "Internal error fetching template version job.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -437,7 +438,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error creating workspace",
|
||||
Message: "Internal error creating workspace.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -445,7 +446,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
user, err := api.Database.GetUserByID(r.Context(), apiKey.UserID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error fetching user",
|
||||
Message: "Internal error fetching user.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -470,7 +471,7 @@ func (api *API) putWorkspaceAutostart(rw http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
api.Logger.Error(r.Context(), "fetch workspace template", slog.F("workspace_id", workspace.ID), slog.F("template_id", workspace.TemplateID), slog.Error(err))
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Error fetching workspace template",
|
||||
Message: "Error fetching workspace template.",
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -478,7 +479,7 @@ func (api *API) putWorkspaceAutostart(rw http.ResponseWriter, r *http.Request) {
|
||||
dbSched, err := validWorkspaceSchedule(req.Schedule, time.Duration(template.MinAutostartInterval))
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: "Invalid autostart schedule",
|
||||
Message: "Invalid autostart schedule.",
|
||||
Validations: []httpapi.Error{{Field: "schedule", Detail: err.Error()}},
|
||||
})
|
||||
return
|
||||
@@ -490,7 +491,7 @@ func (api *API) putWorkspaceAutostart(rw http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error updating workspace autostart schedule",
|
||||
Message: "Internal error updating workspace autostart schedule.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -520,7 +521,7 @@ func (api *API) putWorkspaceTTL(rw http.ResponseWriter, r *http.Request) {
|
||||
dbTTL, err := validWorkspaceTTLMillis(req.TTLMillis, time.Duration(template.MaxTtl))
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: "Invalid workspace TTL",
|
||||
Message: "Invalid workspace TTL.",
|
||||
Detail: err.Error(),
|
||||
Validations: []httpapi.Error{
|
||||
{
|
||||
@@ -538,7 +539,7 @@ func (api *API) putWorkspaceTTL(rw http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: "Internal error updating workspace TTL",
|
||||
Message: "Internal error updating workspace TTL.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -564,20 +565,20 @@ func (api *API) putExtendWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
build, err := s.GetLatestWorkspaceBuildByWorkspaceID(r.Context(), workspace.ID)
|
||||
if err != nil {
|
||||
code = http.StatusInternalServerError
|
||||
resp.Message = "workspace not found"
|
||||
resp.Message = "Workspace not found."
|
||||
return xerrors.Errorf("get latest workspace build: %w", err)
|
||||
}
|
||||
|
||||
if build.Transition != database.WorkspaceTransitionStart {
|
||||
code = http.StatusConflict
|
||||
resp.Message = "workspace must be started, current status: " + string(build.Transition)
|
||||
resp.Message = "Workspace must be started, current status: " + string(build.Transition)
|
||||
return xerrors.Errorf("workspace must be started, current status: %s", build.Transition)
|
||||
}
|
||||
|
||||
newDeadline := req.Deadline.UTC()
|
||||
if err := validWorkspaceDeadline(build.Deadline, newDeadline); err != nil {
|
||||
code = http.StatusBadRequest
|
||||
resp.Message = "bad extend workspace request"
|
||||
resp.Message = "Bad extend workspace request."
|
||||
resp.Validations = append(resp.Validations, httpapi.Error{Field: "deadline", Detail: err.Error()})
|
||||
return err
|
||||
}
|
||||
@@ -589,10 +590,10 @@ func (api *API) putExtendWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
Deadline: newDeadline,
|
||||
}); err != nil {
|
||||
code = http.StatusInternalServerError
|
||||
resp.Message = "failed to extend workspace deadline"
|
||||
resp.Message = "Failed to extend workspace deadline."
|
||||
return xerrors.Errorf("update workspace build: %w", err)
|
||||
}
|
||||
resp.Message = "deadline updated to " + newDeadline.Format(time.RFC3339)
|
||||
resp.Message = "Deadline updated to " + newDeadline.Format(time.RFC3339) + "."
|
||||
|
||||
return nil
|
||||
})
|
||||
@@ -651,7 +652,7 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
workspace, err := api.Database.GetWorkspaceByID(r.Context(), workspace.ID)
|
||||
if err != nil {
|
||||
_ = wsjson.Write(ctx, c, httpapi.Response{
|
||||
Message: "Internal error fetching workspace",
|
||||
Message: "Internal error fetching workspace.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -659,7 +660,7 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
build, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(r.Context(), workspace.ID)
|
||||
if err != nil {
|
||||
_ = wsjson.Write(ctx, c, httpapi.Response{
|
||||
Message: "Internal error fetching workspace build",
|
||||
Message: "Internal error fetching workspace build.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
@@ -685,7 +686,7 @@ func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
err = group.Wait()
|
||||
if err != nil {
|
||||
_ = wsjson.Write(ctx, c, httpapi.Response{
|
||||
Message: "Internal error fetching resource",
|
||||
Message: "Internal error fetching resource.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user