feat: Handle pagination cases where after_id does not exist (#1947)

* feat: Handle pagination cases where after_id does not exist

Throw an error to the user in these cases
- Templateversions
- Workspacebuilds

User pagination does not need it as suspended users still
have rows in the database
This commit is contained in:
Steven Masley
2022-06-02 09:01:45 -05:00
committed by GitHub
parent 419dc6b036
commit b9983e417f
8 changed files with 212 additions and 73 deletions
+42 -13
View File
@@ -51,22 +51,51 @@ func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) {
if !ok {
return
}
req := database.GetWorkspaceBuildByWorkspaceIDParams{
WorkspaceID: workspace.ID,
AfterID: paginationParams.AfterID,
OffsetOpt: int32(paginationParams.Offset),
LimitOpt: int32(paginationParams.Limit),
}
builds, err := api.Database.GetWorkspaceBuildByWorkspaceID(r.Context(), req)
if xerrors.Is(err, sql.ErrNoRows) {
err = nil
}
var builds []database.WorkspaceBuild
// Ensure all db calls happen in the same tx
err := api.Database.InTx(func(store database.Store) error {
var err error
if paginationParams.AfterID != uuid.Nil {
// See if the record exists first. If the record does not exist, the pagination
// query will not work.
_, err := store.GetWorkspaceBuildByID(r.Context(), paginationParams.AfterID)
if err != nil && xerrors.Is(err, sql.ErrNoRows) {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: fmt.Sprintf("record at \"after_id\" (%q) does not exist", paginationParams.AfterID.String()),
})
return err
} else if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("get workspace build at after_id: %s", err),
})
return err
}
}
req := database.GetWorkspaceBuildByWorkspaceIDParams{
WorkspaceID: workspace.ID,
AfterID: paginationParams.AfterID,
OffsetOpt: int32(paginationParams.Offset),
LimitOpt: int32(paginationParams.Limit),
}
builds, err = store.GetWorkspaceBuildByWorkspaceID(r.Context(), req)
if xerrors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("get workspace builds: %s", err),
})
return err
}
return nil
})
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("get workspace builds: %s", err),
})
return
}
jobIDs := make([]uuid.UUID, 0, len(builds))
for _, version := range builds {
jobIDs = append(jobIDs, version.JobID)