Skip to content

Commit

Permalink
fix(dev-server): handle invalid response (#45)
Browse files Browse the repository at this point in the history
* fix(dev-server): handle invalid response

* changeset

* add comment
  • Loading branch information
yusukebe authored Dec 27, 2023
1 parent 679e3bd commit 05b9841
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-spoons-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hono/vite-dev-server': patch
---

fix: handle invalid response
7 changes: 7 additions & 0 deletions packages/dev-server/e2e/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,10 @@ test('Should handle `env.ASSETS.fetch` function', async ({ page }) => {
const data = await response?.json()
expect(data['message']).toBe('Hello')
})

test('Should return an error page - /invalid-response', async ({ page }) => {
const response = await page.goto('/invalid-response')
expect(response?.status()).toBe(500)
expect(await response?.text()).not.toBe('')
expect(await response?.headerValue('content-type')).toMatch(/^text\/html/)
})
5 changes: 5 additions & 0 deletions packages/dev-server/e2e/mock/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,9 @@ app.get('/assets/hello.json', async (c) => {
return c.json(data)
})

// @ts-expect-error the response is string
app.get('/invalid-response', () => {
return '<h1>Hello!</h1>'
})

export default app
4 changes: 2 additions & 2 deletions packages/dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
},
"dependencies": {
"@hono/node-server": "^1.2.0",
"miniflare": "^3.20231016.0",
"miniflare": "^3.20231030.4",
"minimatch": "^9.0.3"
}
}
}
35 changes: 34 additions & 1 deletion packages/dev-server/src/dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,22 @@ export function devServer(options?: DevServerOptions): Plugin {
env = await cloudflarePagesGetEnv(options.cf)()
}

const response = await app.fetch(request, env, {
let response = await app.fetch(request, env, {
waitUntil: async (fn) => fn,
passThroughOnException: () => {
throw new Error('`passThroughOnException` is not supported')
},
})

/**
* If the response is not instance of `Response`, it returns simple HTML with error messages.
*/
if (!(response instanceof Response)) {
const message = 'The response is not an instance of "Response", but: ' + response
console.error(message)
response = createErrorResponse(message)
}

if (
options?.injectClientScript !== false &&
response.headers.get('content-type')?.match(/^text\/html/)
Expand All @@ -108,6 +118,29 @@ export function devServer(options?: DevServerOptions): Plugin {
return plugin
}

function escapeHtml(str: string): string {
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
}

function createErrorResponse(body: BodyInit) {
return new Response(
`<html><body><pre style="white-space:pre-wrap;">${escapeHtml(
body.toString()
)}</pre></body></html>`,
{
status: 500,
headers: {
'content-type': 'text/html;charset=utf-8',
},
}
)
}

function injectStringToResponse(response: Response, content: string) {
const stream = response.body
const newContent = new TextEncoder().encode(content)
Expand Down
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ __metadata:
"@playwright/test": ^1.37.1
glob: ^10.3.10
hono: ^3.11.7
miniflare: ^3.20231016.0
miniflare: ^3.20231030.4
minimatch: ^9.0.3
playwright: ^1.39.0
publint: ^0.2.5
Expand Down Expand Up @@ -3973,7 +3973,7 @@ __metadata:
languageName: node
linkType: hard

"miniflare@npm:^3.20231016.0":
"miniflare@npm:^3.20231030.4":
version: 3.20231030.4
resolution: "miniflare@npm:3.20231030.4"
dependencies:
Expand Down

0 comments on commit 05b9841

Please sign in to comment.