diff --git a/src/adapter/service-worker/handler.test.ts b/src/adapter/service-worker/handler.test.ts index ae44a8246..f9f2bb673 100644 --- a/src/adapter/service-worker/handler.test.ts +++ b/src/adapter/service-worker/handler.test.ts @@ -2,6 +2,31 @@ import { Hono } from '../../hono' import { handle } from './handler' import type { FetchEvent } from './types' +beforeAll(() => { + // fetch errors when it's not bound to globalThis in service worker + // set a fetch stub to emulate that behavior + vi.stubGlobal( + 'fetch', + function fetch(this: undefined | typeof globalThis, arg0: string | Request) { + if (this !== globalThis) { + const error = new Error( + // eslint-disable-next-line quotes + "Failed to execute 'fetch' on 'WorkerGlobalScope': Illegal invocation" + ) + error.name = 'TypeError' + throw error + } + if (arg0 instanceof Request && arg0.url === 'http://localhost/fallback') { + return new Response('hello world') + } + return Response.error() + } + ) +}) +afterAll(() => { + vi.unstubAllGlobals() +}) + describe('handle', () => { it('Success to fetch', async () => { const app = new Hono() @@ -20,6 +45,19 @@ describe('handle', () => { expect(json).toStrictEqual({ hello: 'world' }) }) it('Fallback 404', async () => { + const app = new Hono() + const handler = handle(app) + const text = await new Promise((resolve) => { + handler({ + request: new Request('http://localhost/fallback'), + respondWith(res) { + resolve(res) + }, + } as FetchEvent) + }).then((res) => res.text()) + expect(text).toBe('hello world') + }) + it('Fallback 404 with explicit fetch', async () => { const app = new Hono() const handler = handle(app, { async fetch() { diff --git a/src/adapter/service-worker/handler.ts b/src/adapter/service-worker/handler.ts index a85d6d618..3b255e8de 100644 --- a/src/adapter/service-worker/handler.ts +++ b/src/adapter/service-worker/handler.ts @@ -16,8 +16,8 @@ export const handle = ( opts: { fetch?: typeof fetch } = { - // To use `fetch` on a Service Worker correctly, first refer to `self.fetch`. - fetch: globalThis.self !== undefined ? globalThis.self.fetch : fetch, + // To use `fetch` on a Service Worker correctly, bind it to `globalThis`. + fetch: globalThis.fetch.bind(globalThis), } ): Handler => { return (evt) => {