From 56c91e900aa8fdfbabd13baf6049c8618346b071 Mon Sep 17 00:00:00 2001 From: Matchu Date: Mon, 21 Jun 2021 09:34:05 -0700 Subject: [PATCH] Better error handling when preloading layers I'm seeing uncaught promise rejections in `loadImage`? It's hard to know exactly where it's actually coming from, those _should_ be caught? My guess is that it's coming from canceled images, which are throwing errors even after loading? I don't totally understand how, because looking back, I don't think the `cancel` method was actually called??? Anyway, I fixed it so cancel actually _is_ called, and that we don't throw errors when the canceled image _correctly_ fails to load. This should be more robust either way, but hopefully it also stops the flow of errors? --- src/app/components/OutfitPreview.js | 8 ++------ src/app/util.js | 11 +++++++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/app/components/OutfitPreview.js b/src/app/components/OutfitPreview.js index 55508a0..d4f7dde 100644 --- a/src/app/components/OutfitPreview.js +++ b/src/app/components/OutfitPreview.js @@ -380,10 +380,7 @@ export function usePreloadLayers(layers) { for (const layer of layers) { const imageAssetPromise = loadImage( getBestImageUrlForLayer(layer, { hiResMode }) - ).then((image) => ({ - type: "image", - image, - })); + ); imageAssetPromises.push(imageAssetPromise); if (layer.canvasMovieLibraryUrl) { @@ -393,7 +390,6 @@ export function usePreloadLayers(layers) { const movieAssetPromise = loadMovieLibrary( layer.canvasMovieLibraryUrl ).then((library) => ({ - type: "movie", library, libraryUrl: layer.canvasMovieLibraryUrl, })); @@ -422,7 +418,7 @@ export function usePreloadLayers(layers) { setError(e); // Cancel any remaining promises, if cancelable. - minimalAssetPromises.forEach((p) => p.cancel && p.cancel()); + imageAssetPromises.forEach((p) => p.cancel && p.cancel()); movieAssetPromises.forEach((p) => p.cancel && p.cancel()); }); diff --git a/src/app/util.js b/src/app/util.js index b0841f6..d4842fc 100644 --- a/src/app/util.js +++ b/src/app/util.js @@ -355,10 +355,16 @@ export function useLocalStorage(key, initialValue) { export function loadImage(rawSrc, { crossOrigin = null } = {}) { const src = safeImageUrl(rawSrc, { crossOrigin }); const image = new Image(); + let canceled = false; const promise = new Promise((resolve, reject) => { - image.onload = () => resolve(image); - image.onerror = () => + image.onload = () => { + if (canceled) return; + resolve(image); + }; + image.onerror = () => { + if (canceled) return; reject(new Error(`Failed to load image: ${JSON.stringify(src)}`)); + }; if (crossOrigin) { image.crossOrigin = crossOrigin; } @@ -366,6 +372,7 @@ export function loadImage(rawSrc, { crossOrigin = null } = {}) { }); promise.cancel = () => { image.src = ""; + canceled = true; }; return promise; }