Skip to content
Prev Previous commit
Next Next commit
feat(site): Display build error
  • Loading branch information
BrunoQuaresma committed Mar 30, 2023
commit bebc6aac0c6450b5f1d0747b32156509a6db385c
16 changes: 12 additions & 4 deletions site/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,15 +489,23 @@ export const postWorkspaceBuild = async (
export const startWorkspace = (
workspaceId: string,
templateVersionID: string,
debug = false,
) =>
postWorkspaceBuild(workspaceId, {
transition: "start",
template_version_id: templateVersionID,
log_level: debug ? "debug" : undefined,
})
export const stopWorkspace = (workspaceId: string, debug = false) =>
postWorkspaceBuild(workspaceId, {
transition: "stop",
log_level: debug ? "debug" : undefined,
})
export const deleteWorkspace = (workspaceId: string, debug = false) =>
postWorkspaceBuild(workspaceId, {
transition: "delete",
log_level: debug ? "debug" : undefined,
})
export const stopWorkspace = (workspaceId: string) =>
postWorkspaceBuild(workspaceId, { transition: "stop" })
export const deleteWorkspace = (workspaceId: string) =>
postWorkspaceBuild(workspaceId, { transition: "delete" })

export const cancelWorkspaceBuild = async (
workspaceBuildId: TypesGen.WorkspaceBuild["id"],
Expand Down
17 changes: 13 additions & 4 deletions site/src/components/AlertBanner/AlertBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,14 @@ export const AlertBanner: FC<React.PropsWithChildren<AlertBannerProps>> = ({
spacing={0}
justifyContent="space-between"
>
<Stack direction="row" alignItems="center" spacing={1}>
<Stack
direction="row"
alignItems="center"
spacing={2}
className={classes.fullWidth}
>
{severityConstants[severity].icon}
<Stack spacing={0}>
<Stack spacing={0} className={classes.fullWidth}>
{children}
{alertMessage}
{detail && (
Expand Down Expand Up @@ -94,11 +99,11 @@ const useStyles = makeStyles<Theme, StyleProps>((theme) => ({
borderColor: severityConstants[props.severity].color,
border: `1px solid ${colors.orange[7]}`,
borderRadius: theme.shape.borderRadius,
padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`,
padding: theme.spacing(2),
backgroundColor: `${colors.gray[16]}`,
textAlign: "left",

"& span": {
"& > span": {
paddingTop: `${theme.spacing(0.25)}px`,
},

Expand All @@ -108,4 +113,8 @@ const useStyles = makeStyles<Theme, StyleProps>((theme) => ({
marginRight: `${theme.spacing(1)}px`,
},
}),

fullWidth: {
width: "100%",
},
}))
10 changes: 3 additions & 7 deletions site/src/components/AlertBanner/severityConstants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,20 @@ export const severityConstants: Record<
color: colors.orange[7],
icon: (
<ReportProblemOutlinedIcon
fontSize="small"
style={{ color: colors.orange[7] }}
style={{ color: colors.orange[7], fontSize: 16 }}
/>
),
},
error: {
color: colors.red[7],
icon: (
<ErrorOutlineOutlinedIcon
fontSize="small"
style={{ color: colors.red[7] }}
style={{ color: colors.red[7], fontSize: 16 }}
/>
),
},
info: {
color: colors.blue[7],
icon: (
<InfoOutlinedIcon fontSize="small" style={{ color: colors.blue[7] }} />
),
icon: <InfoOutlinedIcon style={{ color: colors.blue[7], fontSize: 16 }} />,
},
}
4 changes: 2 additions & 2 deletions site/src/components/Logs/Logs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const useStyles = makeStyles<
background: theme.palette.background.default,
},
scrollWrapper: {
width: "fit-content",
minWidth: "fit-content",
},
line: {
wordBreak: "break-all",
Expand All @@ -109,7 +109,7 @@ const useStyles = makeStyles<
},

"&.debug": {
backgroundColor: theme.palette.grey[900],
backgroundColor: theme.palette.background.paperLight,
},

"&.warn": {
Expand Down
52 changes: 46 additions & 6 deletions site/src/components/Workspace/Workspace.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import Button from "@material-ui/core/Button"
import { makeStyles } from "@material-ui/core/styles"
import RefreshOutlined from "@material-ui/icons/RefreshOutlined"
import { Avatar } from "components/Avatar/Avatar"
import { AgentRow } from "components/Resources/AgentRow"
import { WorkspaceBuildLogs } from "components/WorkspaceBuildLogs/WorkspaceBuildLogs"
import {
ActiveTransition,
WorkspaceBuildProgress,
Expand Down Expand Up @@ -55,6 +58,8 @@ export interface WorkspaceProps {
applicationsHost?: string
template?: TypesGen.Template
quota_budget?: number
failedBuildLogs: TypesGen.ProvisionerJobLog[] | undefined
handleBuildRetry: () => void
}

/**
Expand All @@ -80,6 +85,8 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
applicationsHost,
template,
quota_budget,
failedBuildLogs,
handleBuildRetry,
}) => {
const styles = useStyles()
const navigate = useNavigate()
Expand Down Expand Up @@ -177,12 +184,36 @@ export const Workspace: FC<React.PropsWithChildren<WorkspaceProps>> = ({
handleUpdate={handleUpdate}
/>

{workspace.latest_build.job.error && (
<div>
<div>
The build failed. See the logs below for more information.
</div>
</div>
{failedBuildLogs && (
<Stack>
<AlertBanner severity="error">
<Stack
className={styles.fullWidth}
direction="row"
alignItems="center"
justifyContent="space-between"
>
<Stack spacing={0}>
<span>Workspace build failed</span>
<span className={styles.errorDetails}>
{workspace.latest_build.job.error}
</span>
</Stack>

<div>
<Button
onClick={handleBuildRetry}
startIcon={<RefreshOutlined />}
size="small"
variant="outlined"
>
Try again in debug mode
</Button>
</div>
</Stack>
</AlertBanner>
<WorkspaceBuildLogs logs={failedBuildLogs} />
</Stack>
)}

{transitionStats !== undefined && (
Expand Down Expand Up @@ -260,5 +291,14 @@ export const useStyles = makeStyles((theme) => {
logs: {
border: `1px solid ${theme.palette.divider}`,
},

errorDetails: {
color: theme.palette.text.secondary,
fontSize: 12,
},

fullWidth: {
width: "100%",
},
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ const useStyles = makeStyles<
padding: theme.spacing(2),
paddingLeft: theme.spacing(3),
paddingRight: theme.spacing(3),
borderTop: `1px solid ${theme.palette.divider}`,
borderBottom: `1px solid ${theme.palette.divider}`,
backgroundColor: theme.palette.background.paper,
display: "flex",
Expand All @@ -113,6 +114,7 @@ const useStyles = makeStyles<
"&:first-child": {
borderTopLeftRadius: theme.shape.borderRadius,
borderTopRightRadius: theme.shape.borderRadius,
borderTop: 0,
},

"&:last-child": {
Expand All @@ -121,6 +123,10 @@ const useStyles = makeStyles<
borderBottomLeftRadius: theme.shape.borderRadius,
borderBottomRightRadius: theme.shape.borderRadius,
},

"& + $header": {
borderTop: 0,
},
},

duration: {
Expand Down
24 changes: 23 additions & 1 deletion site/src/pages/WorkspacePage/WorkspacePage.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
import { makeStyles } from "@material-ui/core/styles"
import { useQuery } from "@tanstack/react-query"
import { useMachine } from "@xstate/react"
import { getWorkspaceBuildLogs } from "api/api"
import { Workspace } from "api/typesGenerated"
import { AlertBanner } from "components/AlertBanner/AlertBanner"
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"
import { Loader } from "components/Loader/Loader"
import { FC } from "react"
import { FC, useRef } from "react"
import { useParams } from "react-router-dom"
import { quotaMachine } from "xServices/quotas/quotasXService"
import { workspaceMachine } from "xServices/workspace/workspaceXService"
import { WorkspaceReadyPage } from "./WorkspaceReadyPage"

const useFailedBuildLogs = (workspace: Workspace | undefined) => {
const now = useRef(new Date())
return useQuery({
queryKey: ["logs", workspace?.latest_build.id],
queryFn: () => {
if (!workspace) {
throw new Error(
`Build log query being called before workspace is defined`,
)
}

return getWorkspaceBuildLogs(workspace.latest_build.id, now.current)
},
enabled: workspace?.latest_build.job.error !== undefined,
})
}

export const WorkspacePage: FC = () => {
const { username, workspace: workspaceName } = useParams() as {
username: string
Expand All @@ -30,6 +50,7 @@ export const WorkspacePage: FC = () => {
const [quotaState] = useMachine(quotaMachine, { context: { username } })
const { getQuotaError } = quotaState.context
const styles = useStyles()
const failedBuildLogs = useFailedBuildLogs(workspace)

return (
<ChooseOne>
Expand Down Expand Up @@ -66,6 +87,7 @@ export const WorkspacePage: FC = () => {
workspaceState={workspaceState}
quotaState={quotaState}
workspaceSend={workspaceSend}
failedBuildLogs={failedBuildLogs.data}
/>
</Cond>
<Cond>
Expand Down
5 changes: 5 additions & 0 deletions site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useActor } from "@xstate/react"
import { ProvisionerJobLog } from "api/typesGenerated"
import { useDashboard } from "components/Dashboard/DashboardProvider"
import dayjs from "dayjs"
import { useFeatureVisibility } from "hooks/useFeatureVisibility"
Expand Down Expand Up @@ -31,11 +32,13 @@ interface WorkspaceReadyPageProps {
workspaceState: StateFrom<typeof workspaceMachine>
quotaState: StateFrom<typeof quotaMachine>
workspaceSend: (event: WorkspaceEvent) => void
failedBuildLogs: ProvisionerJobLog[] | undefined
}

export const WorkspaceReadyPage = ({
workspaceState,
quotaState,
failedBuildLogs,
workspaceSend,
}: WorkspaceReadyPageProps): JSX.Element => {
const [_, bannerSend] = useActor(
Expand Down Expand Up @@ -85,6 +88,7 @@ export const WorkspaceReadyPage = ({
</Helmet>

<Workspace
failedBuildLogs={failedBuildLogs}
scheduleProps={{
onDeadlineMinus: (hours: number) => {
bannerSend({
Expand Down Expand Up @@ -112,6 +116,7 @@ export const WorkspaceReadyPage = ({
handleUpdate={() => workspaceSend({ type: "UPDATE" })}
handleCancel={() => workspaceSend({ type: "CANCEL" })}
handleSettings={() => navigate("settings")}
handleBuildRetry={() => workspaceSend({ type: "RETRY_BUILD" })}
resources={workspace.latest_build.resources}
builds={builds}
canUpdateWorkspace={canUpdateWorkspace}
Expand Down
Loading