0
0
mirror of https://github.com/honojs/hono.git synced 2024-11-24 19:26:56 +01:00

fix(jsx): await all promises at once to avoid race condition (#3274)

This commit is contained in:
Taku Amano 2024-08-15 20:27:52 +09:00 committed by GitHub
parent 986db292e8
commit a5b2382da6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 3 deletions

View File

@ -112,6 +112,39 @@ describe('JSX middleware', () => {
expect(res.headers.get('Content-Type')).toBe('text/html; charset=UTF-8')
expect(await res.text()).toBe('<html><body><h1>Hello from async component</h1></body></html>')
})
it('Should handle async component error', async () => {
const componentError = new Error('Error from async error component')
const AsyncComponent = async () => {
await new Promise((resolve) => setTimeout(resolve, 10))
return <h1>Hello from async component</h1>
}
const AsyncErrorComponent = async () => {
await new Promise((resolve) => setTimeout(resolve, 0))
throw componentError
}
let raisedError: any
app.onError((e, c) => {
raisedError = e
return c.html('<html><body><h1>Error from onError</h1></body></html>', 500)
})
app.get('/', (c) => {
return c.html(
<>
<AsyncComponent />
<AsyncErrorComponent />
</>
)
})
const res = await app.request('http://localhost/')
expect(res.status).toBe(500)
expect(res.headers.get('Content-Type')).toBe('text/html; charset=UTF-8')
expect(await res.text()).toBe('<html><body><h1>Error from onError</h1></body></html>')
expect(raisedError).toBe(componentError)
})
})
describe('render to string', () => {

View File

@ -56,14 +56,15 @@ export const stringBufferToString = async (
): Promise<HtmlEscapedString> => {
let str = ''
callbacks ||= []
for (let i = buffer.length - 1; ; i--) {
str += buffer[i]
const resolvedBuffer = await Promise.all(buffer)
for (let i = resolvedBuffer.length - 1; ; i--) {
str += resolvedBuffer[i]
i--
if (i < 0) {
break
}
let r = await buffer[i]
let r = resolvedBuffer[i]
if (typeof r === 'object') {
callbacks.push(...((r as HtmlEscapedString).callbacks || []))
}