Compare commits

...

1 Commits

Author SHA1 Message Date
Kit Langton fe75eb9486 fix(image): degrade photon resizer load failure to typed error on workerd
A runtime without a photon wasm artifact (#photon-wasm resolves to the
empty string on workerd) now fails the cached loader with the typed
ResizerUnavailableError by declaration, before touching URLs or module
loading. Previously the wasm path resolution ran synchronously in
Image.Photon.make outside the guarded load; on workerd import.meta.url
is undefined, so new URL(photonWasm, import.meta.url) threw TypeError as
a defect that escaped materializeAttachment's catchTag and turned every
image-bearing prompt into a 500 (the intent documented in
photon-wasm.workerd.ts was clean degradation to byte passthrough).

For runtimes that do have an artifact, the path resolution and the
photon-node import both live inside the tryPromise guard, so any load
failure is the typed error.
2026-08-21 11:12:42 -04:00
+20 -6
View File
@@ -8,13 +8,27 @@ import { DecodeError, ResizerUnavailableError, SizeError } from "../image.js"
const JPEG_QUALITIES = [80, 85, 70, 55, 40]
export const make = Effect.gen(function* () {
;(globalThis as typeof globalThis & { __OPENCODE_PHOTON_WASM_PATH?: string }).__OPENCODE_PHOTON_WASM_PATH =
path.isAbsolute(photonWasm) ? photonWasm : fileURLToPath(new URL(photonWasm, import.meta.url))
const loadPhoton = yield* Effect.cached(
Effect.tryPromise({
try: () => import("@silvia-odwyer/photon-node"),
catch: () => new ResizerUnavailableError(),
}),
// A runtime without a photon wasm artifact (#photon-wasm resolves to the
// empty string on workerd) has no resizer, by declaration: fail typed
// before touching URLs or module loading. The path resolution and import
// for runtimes that DO have an artifact stay inside the guard too — a
// throw outside it (workerd's undefined import.meta.url was one) is a
// defect that escapes the ResizerUnavailableError handling and turns any
// image-bearing prompt into a 500 instead of degrading to passthrough.
photonWasm === ""
? Effect.fail(new ResizerUnavailableError())
: Effect.tryPromise({
try: async () => {
;(
globalThis as typeof globalThis & { __OPENCODE_PHOTON_WASM_PATH?: string }
).__OPENCODE_PHOTON_WASM_PATH = path.isAbsolute(photonWasm)
? photonWasm
: fileURLToPath(new URL(photonWasm, import.meta.url))
return await import("@silvia-odwyer/photon-node")
},
catch: () => new ResizerUnavailableError(),
}),
)
return Effect.fn("Image.Photon.normalize")(function* (
resource: string,