diff --git a/README.md b/README.md index 708bf7e..66bcefd 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ The Worker simply calls `fetch(request)` to reach your origin and separately pos ## Runtime Behavior -- Receives each incoming request, proxies to origin with `fetch`, and returns the origin response. +- Receives each incoming request, proxies to origin with `fetch`, and returns the origin response. If configuration is invalid, logs an error and just proxies (no tracking). - Measures server time (`pf_srv` in seconds), status, and response bytes from `Content-Length` when present. - Builds a Matomo payload with `idsite`, `rec:1`, `recMode:1`, `url`, `source:'Cloudflare'`, `cdt` (UTC `YYYY-MM-DD HH:mm:ss`), and `ua`. - Skips tracking when `URL_EXCLUDE_REGEX` matches; detects downloads via `DOCUMENT_REGEX`; disallowed UAs are skipped by `USER_AGENT_ALLOWLIST_REGEX`. diff --git a/src/index.ts b/src/index.ts index 4f19d42..b0192f0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -41,12 +41,13 @@ export default { env: Env, ctx: WorkerContext ): Promise { - let config: MatomoConfig; + let config: MatomoConfig | null = null; try { config = getConfig(env); } catch (err) { const message = err instanceof Error ? err.message : String(err); - return new Response(`Configuration error: ${message}`, { status: 500 }); + console.error('Configuration error', { error: message }); + return fetch(request); } const log = createLogger(config.logLevel); const start = Date.now(); diff --git a/tests/index.test.ts b/tests/index.test.ts index eb8b38b..7de0037 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -118,13 +118,25 @@ describe('Worker fetch handler', () => { consoleWarn.mockRestore(); }); - it('returns 500 when config is invalid', async () => { + it('returns origin response when config is invalid and skips tracking', async () => { + const originResponse = new Response('origin', { status: 200 }); + const fetchMock = vi.fn().mockResolvedValue(originResponse); + global.fetch = fetchMock as unknown as typeof fetch; + const sendSpy = vi + .spyOn(http, 'sendMatomoHit') + .mockResolvedValue(undefined); + const response = await worker.fetch( new Request('https://example.com/path'), { MATOMO_SITE_ID: '7' } as never, { waitUntil } ); - expect(response.status).toBe(500); + expect(response.status).toBe(200); expect(waitUntil).not.toHaveBeenCalled(); + expect(sendSpy).not.toHaveBeenCalled(); + expect(consoleSpies.error).toHaveBeenCalledWith( + 'Configuration error', + expect.objectContaining({ error: expect.stringContaining('MATOMO_URL') }) + ); }); });