Skip to content

Commit 25fee7c

Browse files
committed
refactor job error messages
1 parent 49dd4be commit 25fee7c

File tree

4 files changed

+73
-133
lines changed

4 files changed

+73
-133
lines changed

src/lib/components/ErrorMessage.stories.svelte

+21-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
__typename: 'WorkloadStatusInvalidNaisYaml',
1515
level: 'ERROR',
1616
detail:
17-
'the domain "roger.com" cannot be used in cluster "dev-gcp"; use one of dev.nav.cloud.nais.io, external.dev.nav.cloud.nais.io, authenticated.dev.nav.cloud.nais.io, .intern.dev.nav.no, .dev-gcp.nav.cloud.nais.io, .ekstern.dev.nav.no, .ansatt.dev.nav.no, .very.intern.dev.nav.no'
17+
'the domain "roger.com" cannot be used in cluster "dev-gcp"; use one of dev.nav.cloud.nais.io, external.dev.nav.cloud.nais.io, authenticated.dev.nav.cloud.nais.io, .intern.dev.nav.no, .dev-gcp.nav.cloud.nais.io, .ekstern.dev.nav.no, .ansatt.dev.nav.no, .very.intern.dev.nav.no',
18+
workloadType: 'App'
1819
}}
1920
/>
2021
</Story>
@@ -25,17 +26,19 @@
2526
__typename: 'WorkloadStatusSynchronizationFailing',
2627
level: 'ERROR',
2728
detail:
28-
'persisting SQLInstance to Kubernetes: validation error: refusing to overwrite manually edited resource; please add the correct ownerReference in order to continue'
29+
'persisting SQLInstance to Kubernetes: validation error: refusing to overwrite manually edited resource; please add the correct ownerReference in order to continue',
30+
workloadType: 'Job'
2931
}}
3032
/>
3133
</Story>
3234

33-
<Story name="Deprecated Image Registru">
35+
<Story name="Deprecated Image Registry">
3436
<ErrorMessage
3537
error={{
3638
__typename: 'WorkloadStatusDeprecatedRegistry',
3739
level: 'WARNING',
38-
registry: 'docker.pkg.github.com'
40+
registry: 'docker.pkg.github.com',
41+
workloadType: 'App'
3942
}}
4043
/>
4144
</Story>
@@ -54,7 +57,20 @@
5457
name: 'bidrag-sak-675cdddb5-vpc6m',
5558
status: { message: 'ImagePullBackOff' }
5659
}
57-
]
60+
],
61+
workloadType: 'App'
62+
}}
63+
/>
64+
</Story>
65+
66+
<Story name="Failed Run">
67+
<ErrorMessage
68+
error={{
69+
__typename: 'WorkloadStatusFailedRun',
70+
level: 'WARNING',
71+
name: 'aareg-sync-konkurser-q4-29028365',
72+
detail: 'Run failed after 7 attempts',
73+
workloadType: 'Job'
5874
}}
5975
/>
6076
</Story>

src/lib/components/ErrorMessage.svelte

+36-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
error:
1010
| ({
1111
level: ValueOf<typeof WorkloadStatusErrorLevel>;
12+
workloadType: 'App' | 'Job';
1213
} & (
1314
| {
1415
__typename: 'WorkloadStatusInvalidNaisYaml' | 'WorkloadStatusSynchronizationFailing';
@@ -24,6 +25,13 @@
2425
name: string;
2526
status: { message: string };
2627
}[];
28+
workloadType: 'App';
29+
}
30+
| {
31+
__typename: 'WorkloadStatusFailedRun';
32+
name: string;
33+
detail: string;
34+
workloadType: 'Job';
2735
}
2836
))
2937
| { __typename: "non-exhaustive; don't match this" };
@@ -46,7 +54,8 @@
4654
WorkloadStatusInvalidNaisYaml: 'Rollout Failed - Invalid Manifest',
4755
WorkloadStatusSynchronizationFailing: 'Rollout Failed - Synchronization Error',
4856
WorkloadStatusDeprecatedRegistry: 'Deprecated Image Registry',
49-
WorkloadStatusNoRunningInstances: 'No Running Instances'
57+
WorkloadStatusNoRunningInstances: 'No Running Instances',
58+
WorkloadStatusFailedRun: 'Job Failed'
5059
};
5160
</script>
5261

@@ -56,32 +65,39 @@
5665
<Heading level="2" size="small">{heading[error.__typename]}</Heading>
5766
{#if error.__typename === 'WorkloadStatusInvalidNaisYaml'}
5867
<BodyLong>
59-
The rollout of your application has failed due to an error in the application manifest.
68+
The rollout of your {error.workloadType === 'Job' ? 'job' : 'application'} has failed due to
69+
an error in the {error.workloadType === 'Job' ? 'job' : 'application'} manifest.
6070
</BodyLong>
6171

6272
<Heading level="3" size="xsmall">Error details</Heading>
6373
<code>{error.detail}</code>
6474

6575
<BodyLong>
66-
To resolve this issue, review the application manifest and correct any errors. Consult the <a
76+
To resolve this issue, review the {error.workloadType === 'Job' ? 'job' : 'application'} manifest
77+
and correct any errors. Consult the
78+
<a
6779
target="_blank"
6880
rel="noopener noreferrer"
69-
href={docURL('/workloads/application/reference/application-spec/')}
70-
>Nais application reference</a
81+
href={docURL(
82+
error.workloadType === 'Job'
83+
? '/workloads/job/reference/naisjob-spec/'
84+
: '/workloads/application/reference/application-spec/'
85+
)}>Nais {error.workloadType === 'Job' ? 'job' : 'application'} reference</a
7186
> for manifest requirements.
7287
</BodyLong>
7388
{:else if error.__typename === 'WorkloadStatusSynchronizationFailing'}
7489
<BodyLong>
75-
The rollout of the application is failing, meaning it is not in sync with the latest
76-
deployment. This may be due to a misconfiguration or a temporary issue, so try again in a
77-
few minutes. If the problem persists, contact the Nais team.
90+
The rollout of the {error.workloadType === 'Job' ? 'job' : 'application'} is failing, meaning
91+
it is not in sync with the latest deployment. This may be due to a misconfiguration or a temporary
92+
issue, so try again in a few minutes. If the problem persists, contact the Nais team.
7893
</BodyLong>
7994

8095
<Heading level="3" size="xsmall">Error details</Heading>
8196
<code>{error.detail}</code>
8297
{:else if error.__typename === 'WorkloadStatusDeprecatedRegistry'}
8398
<BodyLong>
84-
This application is using a deprecated image registry ({error.registry}).
99+
This {error.workloadType === 'Job' ? 'job' : 'application'} is using a deprecated image registry
100+
({error.registry}).
85101
</BodyLong>
86102

87103
<BodyLong
@@ -112,6 +128,17 @@
112128
Check logs if available. If this is unexpected and you cannot resolve the issue, contact
113129
the Nais team.
114130
</BodyLong>
131+
{:else if error.__typename === 'WorkloadStatusFailedRun'}
132+
<BodyLong>The last run of this job failed.</BodyLong>
133+
134+
<div>
135+
<code>{error.name}</code>:
136+
{error.detail}
137+
</div>
138+
139+
<BodyLong>
140+
Check logs if available. If you're unable to resolve the issue, contact the Nais team.
141+
</BodyLong>
115142
{/if}
116143
</div>
117144
</Alert>

src/routes/team/[team]/[env]/app/[app]/+page.svelte

+3-2
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@
6161
case 'WorkloadStatusNoRunningInstances':
6262
return {
6363
...error,
64-
instances: $App.data?.team.environment.application.instances.nodes ?? []
64+
instances: $App.data?.team.environment.application.instances.nodes ?? [],
65+
workloadType: 'App' as const
6566
};
6667
default:
67-
return error;
68+
return error ? { ...error, workloadType: 'App' as const } : undefined;
6869
}
6970
};
7071
</script>

src/routes/team/[team]/[env]/job/[job]/+page.svelte

+13-117
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<script lang="ts">
22
import { page } from '$app/state';
3-
import { graphql, type WorkloadStatusErrorLevel$options } from '$houdini';
3+
import { graphql } from '$houdini';
44
import AggregatedCostForWorkload from '$lib/components/AggregatedCostForWorkload.svelte';
5+
import ErrorMessage from '$lib/components/ErrorMessage.svelte';
56
import Image from '$lib/components/Image.svelte';
67
import NetworkPolicy from '$lib/components/NetworkPolicy.svelte';
78
import Persistence from '$lib/components/persistence/Persistence.svelte';
89
import Secrets from '$lib/components/Secrets.svelte';
910
import WorkloadDeploy from '$lib/components/WorkloadDeploy.svelte';
10-
import { docURL } from '$lib/doc';
1111
import GraphErrors from '$lib/GraphErrors.svelte';
1212
import Time from '$lib/Time.svelte';
13-
import { Alert, BodyLong, BodyShort, Button, Heading } from '@nais/ds-svelte-community';
13+
import { Alert, Button, Heading } from '@nais/ds-svelte-community';
1414
import type { PageProps } from './$houdini';
1515
import Runs from './Runs.svelte';
1616
import Schedule from './Schedule.svelte';
@@ -60,16 +60,11 @@
6060
});
6161
};
6262
63-
const levelVariant = (level?: WorkloadStatusErrorLevel$options) => {
64-
switch (level) {
65-
case 'ERROR':
66-
return 'error';
67-
case 'WARNING':
68-
return 'warning';
69-
case 'TODO':
70-
default:
71-
return 'info';
72-
}
63+
const getError = (type: string) => {
64+
const error = $Job.data?.team.environment.job.status.errors.find(
65+
(error) => error.__typename === type
66+
);
67+
return error ? { ...error, workloadType: 'Job' as const } : undefined;
7368
};
7469
</script>
7570

@@ -79,110 +74,11 @@
7974
{@const job = $Job.data.team.environment.job}
8075
<div class="job-content">
8176
<div style="display:flex; flex-direction: column; gap: 1rem;">
82-
{#if job.status.errors.some((error) => error.__typename === 'WorkloadStatusFailedRun')}
83-
<Alert
84-
variant={levelVariant(
85-
job.status.errors.find((error) => error.__typename === 'WorkloadStatusFailedRun')?.level
86-
)}
87-
>
88-
<div style="display: grid; gap: var(--a-spacing-3);">
89-
<Heading level="2" size="small">Job Failed</Heading>
90-
<BodyLong>The last run of this job failed.</BodyLong>
91-
<div>
92-
<code>
93-
{job.status.errors.find((error) => error.__typename === 'WorkloadStatusFailedRun')
94-
?.name}
95-
</code>:
96-
{job.status.errors.find((error) => error.__typename === 'WorkloadStatusFailedRun')
97-
?.detail}
98-
</div>
99-
<BodyLong>
100-
Check logs if available. If you're unable to resolve the issue, contact the Nais team.
101-
</BodyLong>
102-
</div>
103-
</Alert>
104-
{/if}
105-
106-
{#if job.status.errors.some((error) => error.__typename === 'WorkloadStatusInvalidNaisYaml')}
107-
<Alert
108-
variant={levelVariant(
109-
job.status.errors.find((error) => error.__typename === 'WorkloadStatusInvalidNaisYaml')
110-
?.level
111-
)}
112-
>
113-
<div style="display: grid; gap: var(--a-spacing-3);">
114-
<Heading level="2" size="small">Rollout Failed - Invalid Manifest</Heading>
115-
<BodyLong>
116-
The rollout of your job has failed due to an error in the job manifest.
117-
</BodyLong>
118-
119-
<Heading level="3" size="xsmall">Error details</Heading>
120-
121-
<code style="font-size: 0.8rem; line-height: 1.75;"
122-
>{job.status.errors.find(
123-
(error) => error.__typename === 'WorkloadStatusInvalidNaisYaml'
124-
)?.detail}</code
125-
>
126-
127-
<BodyLong>
128-
To resolve this issue, review the job manifest and correct any errors. Consult the <a
129-
target="_blank"
130-
rel="noopener noreferrer"
131-
href={docURL('/workloads/job/reference/naisjob-spec/')}>Nais job reference</a
132-
> for manifest requirements.
133-
</BodyLong>
134-
</div>
135-
</Alert>
136-
{/if}
137-
{#if job.status.errors.some((error) => error.__typename === 'WorkloadStatusSynchronizationFailing')}
138-
<Alert
139-
variant={levelVariant(
140-
job.status.errors.find(
141-
(error) => error.__typename === 'WorkloadStatusSynchronizationFailing'
142-
)?.level
143-
)}
144-
>
145-
<Heading level="2" size="small" spacing>Rollout Failed - Synchronization Error</Heading>
146-
<BodyLong spacing>
147-
The rollout of the job is failing, meaning it is not in sync with the latest deployment.
148-
This may be due to a misconfiguration or a temporary issue, so try again in a few
149-
minutes. If the problem persists, contact the Nais team.
150-
</BodyLong>
151-
152-
<Heading level="3" size="xsmall" spacing>Error details</Heading>
153-
154-
<code style="font-size: 0.8rem; line-height: 1;"
155-
>{job.status.errors.find(
156-
(error) => error.__typename === 'WorkloadStatusSynchronizationFailing'
157-
)?.detail}</code
158-
>
159-
</Alert>
160-
{/if}
161-
{#if job.status.errors.some((error) => error.__typename === 'WorkloadStatusDeprecatedRegistry')}
162-
<Alert
163-
variant={levelVariant(
164-
job.status.errors.find(
165-
(error) => error.__typename === 'WorkloadStatusDeprecatedRegistry'
166-
)?.level
167-
)}
168-
>
169-
<BodyShort spacing
170-
>This job is using a deprecated image registry ({job.status.errors.find(
171-
(error) => error.__typename === 'WorkloadStatusDeprecatedRegistry'
172-
)?.registry}).</BodyShort
173-
>
174-
175-
<BodyLong
176-
>Starting April 1st, applications and jobs on Nais must use images from Google Artifact
177-
Registry (GAR). The easiest way to ensure that images are stored in GAR is to use Nais'
178-
GitHub Actions in the workflow. <a
179-
href="https://nais.io/log/#2025-02-24-image-policy"
180-
target="_blank"
181-
rel="noopener noreferrer">Read more in Nais announcement</a
182-
>.
183-
</BodyLong>
184-
</Alert>
185-
{/if}
77+
{#each ['WorkloadStatusInvalidNaisYaml', 'WorkloadStatusSynchronizationFailing', 'WorkloadStatusFailedRun', 'WorkloadStatusDeprecatedRegistry'].map(getError) as error}
78+
{#if error}
79+
<ErrorMessage {error} />
80+
{/if}
81+
{/each}
18682

18783
{#if job.deletionStartedAt}
18884
<Alert variant="info" size="small" fullWidth={false}>

0 commit comments

Comments
 (0)