Skip to content

Commit 0ee7ce1

Browse files
thongdoanyusukebe
andauthored
fix(serve-static): Add error handling in createStreamBody (#278)
* Add error handling in createStreamBody Fix unhandled 'error' event in createStreamBody, which caused Hono server to crash when attempting to serve an existing file without read permission. Now, such errors are properly handled to prevent server crashes. * add test * test skips on Windows --------- Co-authored-by: Yusuke Wada <yusuke@kamawada.com>
1 parent f3156d9 commit 0ee7ce1

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/serve-static.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ const createStreamBody = (stream: ReadStream) => {
3232
stream.on('data', (chunk) => {
3333
controller.enqueue(chunk)
3434
})
35+
stream.on('error', (err) => {
36+
controller.error(err)
37+
})
3538
stream.on('end', () => {
3639
controller.close()
3740
})

test/serve-static.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Hono } from 'hono'
22
import request from 'supertest'
3+
import { chmodSync, statSync } from 'node:fs'
34
import path from 'node:path'
45
import { serveStatic } from './../src/serve-static'
56
import { createAdaptorServer } from './../src/server'
@@ -331,6 +332,34 @@ describe('Serve Static Middleware', () => {
331332
expect(res.status).toBe(200)
332333
})
333334
})
335+
336+
describe('Stream error handling', () => {
337+
const testFile = path.join(__dirname, 'assets', 'static', 'plain.txt')
338+
console.log(testFile)
339+
let originalMode: number
340+
341+
beforeEach(() => {
342+
const stats = statSync(testFile)
343+
originalMode = stats.mode
344+
// Remove read permission to trigger stream error
345+
chmodSync(testFile, 0o000)
346+
})
347+
348+
afterEach(() => {
349+
chmodSync(testFile, originalMode)
350+
})
351+
352+
// Skip on Windows as chmod doesn't work for file permissions
353+
;(process.platform === 'win32' ? it.skip : it)(
354+
'Should handle read permission errors gracefully',
355+
async () => {
356+
const app = new Hono()
357+
app.use('/static/*', serveStatic({ root: './test/assets' }))
358+
const server = createAdaptorServer(app)
359+
await expect(request(server).get('/static/plain.txt')).rejects.toThrow()
360+
}
361+
)
362+
})
334363
})
335364

336365
describe('Serve Static Middleware with wrong path', () => {

0 commit comments

Comments
 (0)