Non-blocking findings from the code review of #364 and #365 (both merged to dev). None is a defect; each is a bounded improvement worth landing separately.
From #364 (presign error body surfacing)
- HTML error pages leak into
error.message — parseErrorBody's text fallback (body.slice(0, 200)) catches reverse-proxy/CDN error pages (nginx/Cloudflare 502/413), so onError receives 200 chars of raw HTML where it used to get the clean Presign request failed: 502 Bad Gateway. Cheap guard: when the parse produced no code and the body starts with <, fall back to the legacy wording. (packages/core/src/strategies/token-endpoint.ts:146)
- Panel message is the missing half — the surfaced host error code renders in the default panel as
uploadFailedWithCode ("Upload failed with error code: {code}"), not the host's sentence. A follow-up that prefers a body-supplied message over the generic key would complete the feature for non-headless users.
- (Cosmetic)
error.message is reassigned after construction, so the V8 .stack header shows the pre-fallback message; computing the message before constructing also drops a redundant second parseErrorBody call.
From #365 (animated images skip canvas re-encode)
- No runtime signal when EXIF strip is skipped — a privacy-sensitive host cannot detect that an animated WebP/APNG kept its metadata (both formats carry EXIF). Cheap version: a
metadata marker or a pipeline-error-style diagnostic so the host can branch server-side. (Lossless chunk-drop metadata stripping for these containers would be the real feature, out of scope.)
isAnimatedImage reads the whole file on the main-thread path — decodeImage never materialized an ArrayBuffer before; the sniff now allocates the full file even for large still images. Bounded fix: sniff file.slice(0, 64 * 1024) (sufficient for APNG acTL, WebP VP8X/ANIM, and the GIF NETSCAPE2.0 short-circuit) and fall back to a full read only for the multi-descriptor GIF walk.
- (Accepted behavior, documenting) A still GIF carrying an unconditional
NETSCAPE2.0 extension is a false positive that skips both steps — fail-safe direction, leave as is.
Non-blocking findings from the code review of #364 and #365 (both merged to dev). None is a defect; each is a bounded improvement worth landing separately.
From #364 (presign error body surfacing)
error.message—parseErrorBody's text fallback (body.slice(0, 200)) catches reverse-proxy/CDN error pages (nginx/Cloudflare 502/413), soonErrorreceives 200 chars of raw HTML where it used to get the cleanPresign request failed: 502 Bad Gateway. Cheap guard: when the parse produced nocodeand the body starts with<, fall back to the legacy wording. (packages/core/src/strategies/token-endpoint.ts:146)uploadFailedWithCode("Upload failed with error code: {code}"), not the host's sentence. A follow-up that prefers a body-supplied message over the generic key would complete the feature for non-headless users.error.messageis reassigned after construction, so the V8.stackheader shows the pre-fallback message; computing the message before constructing also drops a redundant secondparseErrorBodycall.From #365 (animated images skip canvas re-encode)
metadatamarker or apipeline-error-style diagnostic so the host can branch server-side. (Lossless chunk-drop metadata stripping for these containers would be the real feature, out of scope.)isAnimatedImagereads the whole file on the main-thread path —decodeImagenever materialized an ArrayBuffer before; the sniff now allocates the full file even for large still images. Bounded fix: snifffile.slice(0, 64 * 1024)(sufficient for APNGacTL, WebPVP8X/ANIM, and the GIFNETSCAPE2.0short-circuit) and fall back to a full read only for the multi-descriptor GIF walk.NETSCAPE2.0extension is a false positive that skips both steps — fail-safe direction, leave as is.