Skip to content

Commit 8f1d18b

Browse files
dahliacodex
andcommitted
Improve suppressed recurse diagnostics and output/body error handling
Add debug logging for suppressed recursive lookup failures so best-effort runs leave traceable diagnostics for both thrown lookup errors and not-found results. In traverse mode, isolate output writing failures from traversal/fetch failures by handling separator/object write errors in an inner try/catch and failing with an output-specific message. For image downloads, cancel non-OK terminal response bodies before returning null to avoid retaining response body resources in manual-fetch paths. #608 (comment) #608 (comment) #608 (comment) #608 (comment) Co-Authored-By: Codex <codex@openai.com>
1 parent 5101c9c commit 8f1d18b

3 files changed

Lines changed: 61 additions & 12 deletions

File tree

packages/cli/src/imagerenderer.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,24 @@ test("downloadImage - cancels redirect body when location is missing", async ()
149149
globalThis.fetch = originalFetch;
150150
}
151151
});
152+
153+
test("downloadImage - cancels body for non-ok terminal response", async () => {
154+
let cancelled = 0;
155+
const originalFetch = globalThis.fetch;
156+
globalThis.fetch = ((_input: URL | RequestInfo) => {
157+
const body = new ReadableStream<Uint8Array>({
158+
cancel() {
159+
cancelled++;
160+
},
161+
});
162+
return Promise.resolve(new Response(body, { status: 500 }));
163+
}) as typeof fetch;
164+
165+
try {
166+
const result = await downloadImage("https://example.com/image.png");
167+
assert.equal(result, null);
168+
assert.equal(cancelled, 1);
169+
} finally {
170+
globalThis.fetch = originalFetch;
171+
}
172+
});

packages/cli/src/imagerenderer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ export async function downloadImage(url: string): Promise<string | null> {
125125
}
126126
break;
127127
}
128-
if (response == null || !response.ok) return null;
128+
if (response == null) return null;
129+
if (!response.ok) {
130+
await response.body?.cancel();
131+
return null;
132+
}
129133
const imageData = new Uint8Array(await response.arrayBuffer());
130134
const extension = new URL(targetUrl).pathname.split(".").pop() || "jpg";
131135
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "fedify"));

packages/cli/src/lookup.ts

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -534,11 +534,25 @@ export async function collectRecursiveObjects(
534534
try {
535535
next = await lookup(target);
536536
} catch (error) {
537-
if (options.suppressErrors) break;
537+
if (options.suppressErrors) {
538+
logger.debug(
539+
"Failed to recursively fetch object {target}, " +
540+
"but suppressing error: {error}",
541+
{ target, error },
542+
);
543+
break;
544+
}
538545
throw error;
539546
}
540547
if (next == null) {
541-
if (options.suppressErrors) break;
548+
if (options.suppressErrors) {
549+
logger.debug(
550+
"Failed to recursively fetch object {target} " +
551+
"(not found), but suppressing error.",
552+
{ target },
553+
);
554+
break;
555+
}
542556
throw new RecursiveLookupError(target);
543557
}
544558
results.push(next);
@@ -950,16 +964,26 @@ export async function runLookup(
950964
suppressError: command.suppressErrors,
951965
})
952966
) {
953-
if (totalItems > 0 || collectionItems > 0) {
954-
await writeSeparator(command.separator, getOutputStream());
967+
try {
968+
if (totalItems > 0 || collectionItems > 0) {
969+
await writeSeparator(command.separator, getOutputStream());
970+
}
971+
await writeObjectToStream(
972+
item,
973+
command.output,
974+
command.format,
975+
contextLoader,
976+
getOutputStream(),
977+
);
978+
} catch (error) {
979+
logger.error("Failed to write output for {url}: {error}", {
980+
url,
981+
error,
982+
});
983+
spinner.fail(`Failed to write output for: ${colors.red(url)}.`);
984+
await finalizeAndExit(1);
985+
return;
955986
}
956-
await writeObjectToStream(
957-
item,
958-
command.output,
959-
command.format,
960-
contextLoader,
961-
getOutputStream(),
962-
);
963987
collectionItems++;
964988
totalItems++;
965989
}

0 commit comments

Comments
 (0)