Skip to content

Commit d7665cd

Browse files
committed
Render error page on theme asset upload error
1 parent dd17d8a commit d7665cd

File tree

2 files changed

+46
-20
lines changed

2 files changed

+46
-20
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
interface Error {
2+
message: string
3+
code: string
4+
}
5+
6+
export function getErrorPage(options: {title: string; header: string; errors: Error[]}) {
7+
const html = String.raw
8+
9+
return html`<html>
10+
<head>
11+
<title>${options.title ?? 'Unknown error'}</title>
12+
</head>
13+
<body
14+
id="full-error-page"
15+
style="display: flex; flex-direction: column; align-items: center; padding-top: 20px; font-family: Arial"
16+
>
17+
<h1>${options.header}</h1>
18+
19+
${options.errors
20+
.map(
21+
(error) =>
22+
`<p>${error.message}</p>
23+
<pre>${error.code}</pre>`,
24+
)
25+
.join('')}
26+
</body>
27+
</html>`
28+
}

packages/theme/src/cli/utilities/theme-environment/html.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {getProxyStorefrontHeaders, patchRenderingResponse} from './proxy.js'
22
import {getInMemoryTemplates, injectHotReloadScript} from './hot-reload/server.js'
33
import {render} from './storefront-renderer.js'
4+
import {getErrorPage} from './hot-reload/error-page.js'
45
import {getExtensionInMemoryTemplates} from '../theme-ext-environment/theme-ext-server.js'
56
import {logRequestLine} from '../log-request-line.js'
67
import {defineEventHandler, getCookie, setResponseHeader, setResponseStatus, type H3Error} from 'h3'
@@ -31,6 +32,17 @@ export function getHtmlHandler(theme: Theme, ctx: DevServerContext) {
3132

3233
assertThemeId(response, html, String(theme.id))
3334

35+
if (ctx.localThemeFileSystem.uploadErrors.size > 0) {
36+
html = getErrorPage({
37+
title: 'Failed to Upload Theme Files',
38+
header: 'Upload Errors',
39+
errors: Array.from(ctx.localThemeFileSystem.uploadErrors.entries()).map(([file, errors]) => ({
40+
message: file,
41+
code: errors.join('\n'),
42+
})),
43+
})
44+
}
45+
3446
if (ctx.options.liveReload !== 'off') {
3547
html = injectHotReloadScript(html)
3648
}
@@ -52,8 +64,12 @@ export function getHtmlHandler(theme: Theme, ctx: DevServerContext) {
5264
let errorPageHtml = getErrorPage({
5365
title,
5466
header: title,
55-
message: [...rest, cause?.message ?? error.message].join('<br>'),
56-
code: error.stack?.replace(`${error.message}\n`, '') ?? '',
67+
errors: [
68+
{
69+
message: [...rest, cause?.message ?? error.message].join('<br>'),
70+
code: error.stack?.replace(`${error.message}\n`, '') ?? '',
71+
},
72+
],
5773
})
5874

5975
if (ctx.options.liveReload !== 'off') {
@@ -65,24 +81,6 @@ export function getHtmlHandler(theme: Theme, ctx: DevServerContext) {
6581
})
6682
}
6783

68-
function getErrorPage(options: {title: string; header: string; message: string; code: string}) {
69-
const html = String.raw
70-
71-
return html`<html>
72-
<head>
73-
<title>${options.title ?? 'Unknown error'}</title>
74-
</head>
75-
<body
76-
id="full-error-page"
77-
style="display: flex; flex-direction: column; align-items: center; padding-top: 20px; font-family: Arial"
78-
>
79-
<h2>${options.header}</h2>
80-
<p>${options.message}</p>
81-
<pre>${options.code}</pre>
82-
</body>
83-
</html>`
84-
}
85-
8684
function assertThemeId(response: Response, html: string, expectedThemeId: string) {
8785
/**
8886
* DOM example:

0 commit comments

Comments
 (0)