()
| 210 | } |
| 211 | |
| 212 | func (u *updater) buildUpdate() bool { |
| 213 | build, err := u.db.GetLatestWorkspaceBuildWithStatusByWorkspaceID(u.connCtx, u.workspaceID) |
| 214 | if err != nil { |
| 215 | retryable := true |
| 216 | details := err.Error() |
| 217 | if errors.Is(err, sql.ErrNoRows) { |
| 218 | // There is no build (unlikely), or the workspace was deleted. In both cases, retrying won't help. |
| 219 | retryable = false |
| 220 | } |
| 221 | if dbauthz.IsNotAuthorizedError(err) { |
| 222 | retryable = false |
| 223 | details = "unauthorized" // security: don't leak internal authz details |
| 224 | } |
| 225 | u.errorThenClose(workspacesdk.WatchError{ |
| 226 | Code: workspacesdk.WatchErrorDatabase, |
| 227 | Retryable: retryable, |
| 228 | Message: "failed to fetch latest workspace build", |
| 229 | Details: details, |
| 230 | }) |
| 231 | return false |
| 232 | } |
| 233 | |
| 234 | if build.BuildNumber != u.lastBuild.BuildNumber || |
| 235 | build.JobStatus != u.lastBuild.JobStatus || |
| 236 | build.Transition != u.lastBuild.Transition { |
| 237 | u.lastBuild = build |
| 238 | err = u.enc.Encode(workspacesdk.ConnectionWatchEvent{BuildUpdate: &workspacesdk.BuildUpdate{ |
| 239 | Transition: codersdk.WorkspaceTransition(build.Transition), |
| 240 | JobStatus: codersdk.ProvisionerJobStatus(build.JobStatus), |
| 241 | }}) |
| 242 | if err != nil { |
| 243 | // probably this is just that the connection is closed, but in case there is some actual JSON serialization |
| 244 | // error, send a close frame. |
| 245 | _ = u.conn.Close(websocket.StatusInternalError, "failed to encode build update") |
| 246 | return false |
| 247 | } |
| 248 | return u.maybeSendAgentUpdate() |
| 249 | } |
| 250 | return true |
| 251 | } |
| 252 | |
| 253 | func (u *updater) maybeSendAgentUpdate() (ok bool) { |
| 254 | if u.lastBuild.Transition != database.WorkspaceTransitionStart || |
no test coverage detected