Skip to content

Commit

Permalink
Render error overlay when themeFileSystem has upload errors
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesmengo committed Jan 15, 2025
1 parent f0cb515 commit 296bee3
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const OVERLAY_STYLES = {
container: `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
`,
dialog: `
background: rgba(200, 200, 200, 0.9);
backdrop-filter: blur(10px);
border-radius: 10px;
padding: 20px;
font-family: system-ui, -apple-system, sans-serif;
max-width: 80%;
max-height: 80%;
box-shadow: 0px 0px 10px rgba(0,0,0,0.5);
position: relative;
overflow-y: auto;
`,
closeButton: `
position: absolute;
top: 10px;
right: 10px;
background: transparent;
border: none;
font-size: 16px;
cursor: pointer;
`,
errorItem: `
margin-bottom: 16px;
text-align: left;
`,
errorMessage: `
margin: 8px 0;
white-space: normal;
word-wrap: break-word;
`,
}

export function getErrorOverlay(errors: Map<string, string[]>): string {
const errorContent = Array.from(errors.entries())
.map(
([fileKey, messages]) => `
<div style="${OVERLAY_STYLES.errorItem}">
<strong>${fileKey}</strong>
${messages.map((msg) => `<pre style="${OVERLAY_STYLES.errorMessage}">- ${msg}</pre>`).join('')}
</div>
`,
)
.join('')

return `
<div id="section-error-overlay" style="${OVERLAY_STYLES.container}">
<div style="${OVERLAY_STYLES.dialog}">
${errorContent}
<button
style="${OVERLAY_STYLES.closeButton}"
onclick="document.getElementById('section-error-overlay').style.display='none';"
>
&times;
</button>
</div>
</div>
`
}

export function injectErrorIntoHtml(html: string, errors: Map<string, string[]>): string {
return html + getErrorOverlay(errors)
}
40 changes: 40 additions & 0 deletions packages/theme/src/cli/utilities/theme-environment/html.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {getErrorOverlay, injectErrorIntoHtml} from './hot-reload/error-overlay.js'
import {describe, expect, test} from 'vitest'

describe('html', () => {
test('injects error overlay into HTML with body tag', () => {
// Given
const html = '<html><head></head><body><div>content</div></body></html>'
const errors = new Map([
['assets/theme.css', ['Syntax error in line 10']],
['sections/header.liquid', ['Missing end tag', 'Invalid liquid syntax']],
])

// When
const result = injectErrorIntoHtml(html, errors)

// Then
const overlay = getErrorOverlay(errors)
expect(result).toBe(html.replace('<body>', `<body>${overlay}`))
expect(result).toContain('assets/theme.css')
expect(result).toContain('Syntax error in line 10')
expect(result).toContain('sections/header.liquid')
expect(result).toContain('Missing end tag')
expect(result).toContain('Invalid liquid syntax')
})

test('preserves original HTML content', () => {
// Given
const html = '<html><head><title>My Store</title></head><body><div>content</div></body></html>'
const errors = new Map([['file.css', ['Error']]])

// When
const result = injectErrorIntoHtml(html, errors)

// Then
const overlay = getErrorOverlay(errors)
expect(result).toBe(html.replace('<body>', `<body>${overlay}`))
expect(result).toContain('<title>My Store</title>')
expect(result).toContain('<div>content</div>')
})
})
5 changes: 5 additions & 0 deletions packages/theme/src/cli/utilities/theme-environment/html.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {getProxyStorefrontHeaders, patchRenderingResponse} from './proxy.js'
import {getInMemoryTemplates, injectHotReloadScript} from './hot-reload/server.js'
import {render} from './storefront-renderer.js'
import {injectErrorIntoHtml} from './hot-reload/error-overlay.js'
import {getExtensionInMemoryTemplates} from '../theme-ext-environment/theme-ext-server.js'
import {logRequestLine} from '../log-request-line.js'
import {defineEventHandler, getCookie, setResponseHeader, setResponseStatus, type H3Error} from 'h3'
Expand Down Expand Up @@ -35,6 +36,10 @@ export function getHtmlHandler(theme: Theme, ctx: DevServerContext) {
html = injectHotReloadScript(html)
}

if (ctx.localThemeFileSystem.uploadErrors.size > 0) {
html = injectErrorIntoHtml(html, ctx.localThemeFileSystem.uploadErrors)
}

return html
})
.catch(async (error: H3Error<{requestId?: string; url?: string}>) => {
Expand Down

0 comments on commit 296bee3

Please sign in to comment.