From 2e1839f89837eb64955aee16646381b3be7a3333 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 11 Jun 2026 13:23:50 +0000 Subject: [PATCH] :bug: Fix NotReadableError in rasterizer during thumbnail generation The rasterizer's create-image function was clearing image.src in its Rx teardown cleanup. This caused the decoded pixel data to be discarded before downstream operators (drawImage / createImageBitmap) could read it, resulting in a browser NotReadableError. Changes: - Remove image.src = "" from cleanup; the image element will be garbage collected naturally. Event handler nulling is kept to break circular references. - Add dimension validation in svg-get-adjusted-size to return nil for zero/NaN dimensions instead of producing invalid sizes. - Add fallback in svg-set-intrinsic-size! to use [max max] when SVG dimensions can't be determined. Error occurred in production (2.16.0-RC10) during thumbnail generation in the workspace. Signed-off-by: Andrey Antukh --- frontend/src/app/rasterizer.cljs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/rasterizer.cljs b/frontend/src/app/rasterizer.cljs index 66f906686f..ed516fc85f 100644 --- a/frontend/src/app/rasterizer.cljs +++ b/frontend/src/app/rasterizer.cljs @@ -49,7 +49,14 @@ :hint "operation aborted"))) (obj/set! image "src" uri) (fn [] - (obj/set! image "src" "") + ;; NOTE: We intentionally do NOT set `image.src = ""` here. + ;; Doing so discards the decoded pixel data immediately when this + ;; observable completes, but downstream operators (e.g. drawImage / + ;; createImageBitmap in `render-image-bitmap`) still need to read + ;; the pixel data after the image is emitted. Clearing `src` before + ;; the downstream pipeline finishes causes a NotReadableError + ;; ("The requested file could not be read..."). The image element + ;; will be garbage collected naturally when no references remain. (obj/set! image "onload" nil) (obj/set! image "onerror" nil) (obj/set! image "onabort" nil)))))) @@ -57,10 +64,13 @@ (defn- svg-get-adjusted-size "Returns the adjusted size of an SVG." [width height max] - (let [ratio (/ width height)] - (if (< width height) - [max (* max (/ 1 ratio))] - [(* max ratio) max]))) + ;; Guard against zero/NaN dimensions that would cause division by zero + ;; or produce invalid sizes, leading to createImageBitmap failures. + (when (and (pos? width) (pos? height)) + (let [ratio (/ width height)] + (if (< width height) + [max (* max (/ 1 ratio))] + [(* max ratio) max])))) (defn- svg-get-size-from-viewbox "Returns the size of an SVG from its viewbox." @@ -101,7 +111,10 @@ "Sets the intrinsic size of an SVG to the given max size." [^js svg max] (let [doc (get-document-element svg) - [w h] (svg-get-size svg max)] + [w h] (or (svg-get-size svg max) + ;; Fallback: if we can't determine size from viewBox or + ;; intrinsic attributes, use the max size as a square. + [max max])] (dom/set-attribute! doc "width" (dm/str w)) (dom/set-attribute! doc "height" (dm/str h))) svg)