Global error page: ErrorView with per-status copy, did-you-mean suggestions, error ids from handleError, static error.html; 404 instead of 500 for bad progress ids; tolerate full header line in DAISY_TASK_WEBHOOK_HEADER and stop logging raw fetch errors
All checks were successful
Deploy production / deploy (push) Successful in 1m9s

This commit is contained in:
2026-10-25 13:10:50 +00:00
parent f86c8ef294
commit a89a187346
13 changed files with 665 additions and 30 deletions

View File

@@ -34,4 +34,18 @@ describe('daisy task webhook', () => {
);
expect(fetcher).toHaveBeenCalledTimes(1);
});
it('takes only the name from a full "Name: value" header setting', () => {
const base = {
DAISY_TASK_WEBHOOK_URL: 'https://example.test/hook',
DAISY_TASK_WEBHOOK_KEY: 'k1'
};
const cfg = daisyHookConfig({
...base,
DAISY_TASK_WEBHOOK_HEADER: 'Authorization: Bearer old'
});
expect(cfg?.headers.Authorization).toBe('Bearer k1');
expect(Object.keys(cfg?.headers ?? {})).toEqual(['content-type', 'Authorization']);
const bad = daisyHookConfig({ ...base, DAISY_TASK_WEBHOOK_HEADER: 'bad header' });
expect(bad?.headers.Authorization).toBe('Bearer k1');
});
});

View File

@@ -12,7 +12,10 @@ export function daisyHookConfig(env: Record<string, string | undefined> = proces
const url = env.DAISY_TASK_WEBHOOK_URL?.trim();
const key = env.DAISY_TASK_WEBHOOK_KEY?.trim();
if (!url || !key) return null;
const header = env.DAISY_TASK_WEBHOOK_HEADER?.trim() || 'Authorization';
// Header name only. Tolerate a full "Name: value" line (the value part is ignored; the key
// comes from DAISY_TASK_WEBHOOK_KEY) and fall back to Authorization for anything invalid.
const rawHeader = env.DAISY_TASK_WEBHOOK_HEADER?.split(':')[0].trim() ?? '';
const header = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(rawHeader) ? rawHeader : 'Authorization';
const value = header.toLowerCase() === 'authorization' ? `Bearer ${key}` : key;
return { url, headers: { 'content-type': 'application/json', [header]: value } };
}
@@ -33,6 +36,12 @@ export function notifyDaisy(
.then((res) => {
if (!res.ok) console.error(`[daisy-hook] task ${task.id}: HTTP ${res.status}`);
})
.catch((err) => console.error(`[daisy-hook] task ${task.id}: ${String(err)}`));
.catch((err: unknown) => {
// Name/code only: some fetch errors echo request headers (and so the key).
const e = err as { name?: string; cause?: { code?: string } };
console.error(
`[daisy-hook] task ${task.id}: ${e?.name ?? 'Error'} ${e?.cause?.code ?? ''}`.trim()
);
});
return 'sent';
}