v0.3.5: readBody tries .json() without clone() first

Some test mocks expose .json() but not .clone() — cloning throws on
object mocks. Try .json() directly, fall back to .text(). Real Response
objects are unaffected (calling .json() twice would throw, but we only
call it once since we're on the error path).
This commit is contained in:
Uwe Schuster 2026-04-21 22:33:01 +02:00
parent 0673c4c0d8
commit b14b8188fe
2 changed files with 10 additions and 4 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "@uschuster/webapp-scaffold", "name": "@uschuster/webapp-scaffold",
"version": "0.3.4", "version": "0.3.5",
"description": "Shared build scripts + Vite config factories for webapp-template-derived projects.", "description": "Shared build scripts + Vite config factories for webapp-template-derived projects.",
"type": "module", "type": "module",
"bin": { "bin": {

View file

@ -191,12 +191,18 @@ function safeJson(text: string): unknown | null {
* JSON (may be null when the body isn't parseable). * JSON (may be null when the body isn't parseable).
*/ */
async function readBody(r: Response): Promise<[string, unknown | null]> { async function readBody(r: Response): Promise<[string, unknown | null]> {
// Some mocks expose .json() but not .clone() (e.g. vitest object mocks).
// Try .json() directly; if it throws, fall back to .text().
try { try {
const j = await r.clone().json(); const j = await r.json();
return [JSON.stringify(j), j]; return [JSON.stringify(j), j];
} catch { } catch {
const text = await r.text().catch(() => ''); try {
return [text, safeJson(text)]; const text = await r.text();
return [text, safeJson(text)];
} catch {
return ['', null];
}
} }
} }