diff --git a/src/serve-static.ts b/src/serve-static.ts index 5de5639..f72d425 100644 --- a/src/serve-static.ts +++ b/src/serve-static.ts @@ -32,6 +32,9 @@ const createStreamBody = (stream: ReadStream) => { stream.on('data', (chunk) => { controller.enqueue(chunk) }) + stream.on('error', (err) => { + controller.error(err) + }) stream.on('end', () => { controller.close() }) diff --git a/test/serve-static.test.ts b/test/serve-static.test.ts index 76e72e0..d35f751 100644 --- a/test/serve-static.test.ts +++ b/test/serve-static.test.ts @@ -1,5 +1,6 @@ import { Hono } from 'hono' import request from 'supertest' +import { chmodSync, statSync } from 'node:fs' import path from 'node:path' import { serveStatic } from './../src/serve-static' import { createAdaptorServer } from './../src/server' @@ -331,6 +332,34 @@ describe('Serve Static Middleware', () => { expect(res.status).toBe(200) }) }) + + describe('Stream error handling', () => { + const testFile = path.join(__dirname, 'assets', 'static', 'plain.txt') + console.log(testFile) + let originalMode: number + + beforeEach(() => { + const stats = statSync(testFile) + originalMode = stats.mode + // Remove read permission to trigger stream error + chmodSync(testFile, 0o000) + }) + + afterEach(() => { + chmodSync(testFile, originalMode) + }) + + // Skip on Windows as chmod doesn't work for file permissions + ;(process.platform === 'win32' ? it.skip : it)( + 'Should handle read permission errors gracefully', + async () => { + const app = new Hono() + app.use('/static/*', serveStatic({ root: './test/assets' })) + const server = createAdaptorServer(app) + await expect(request(server).get('/static/plain.txt')).rejects.toThrow() + } + ) + }) }) describe('Serve Static Middleware with wrong path', () => {