From 972be117cb46ce4e8b75fecbe87d3f22e80f8397 Mon Sep 17 00:00:00 2001 From: corpi Date: Wed, 11 Mar 2026 15:16:00 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=A7=A4=EB=8B=88=ED=8E=98=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A1=9C=EB=93=9C=20=EC=8B=A4=ED=8C=A8=20=EC=8B=9C?= =?UTF-8?q?=20=EB=A1=9C=EC=BB=AC=20=EC=9E=90=EC=82=B0=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=95=88=EC=A0=84=ED=95=98=EA=B2=8C=20=EB=8C=80=EC=B2=B4?= =?UTF-8?q?=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - normalizeMediaManifest에서 빈 데이터 수신 시 DEFAULT_MEDIA_MANIFEST를 활용하도록 수정 - 매니페스트 로드 실패 시 상세 정보(URL, 상태 코드)를 에러 메시지에 포함 - useMediaCatalog에서 fetch 에러 발생 시 명시적으로 로컬 기반 매니페스트를 적용하도록 보강 --- src/entities/media/api/mediaManifestApi.ts | 29 ++++++++++++------- src/entities/media/model/resolveMediaAsset.ts | 12 ++++---- src/entities/media/model/useMediaCatalog.ts | 12 ++++++-- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/entities/media/api/mediaManifestApi.ts b/src/entities/media/api/mediaManifestApi.ts index 9460f23..785704c 100644 --- a/src/entities/media/api/mediaManifestApi.ts +++ b/src/entities/media/api/mediaManifestApi.ts @@ -36,17 +36,26 @@ export const mediaManifestApi = { return DEFAULT_MEDIA_MANIFEST; } - const response = await fetch(MEDIA_MANIFEST_URL, { - method: 'GET', - cache: MEDIA_MANIFEST_FETCH_CACHE, - signal, - }); + try { + const response = await fetch(MEDIA_MANIFEST_URL, { + method: 'GET', + cache: MEDIA_MANIFEST_FETCH_CACHE, + signal, + }); - if (!response.ok) { - throw new Error(copy.media.manifestLoadFailed); + if (!response.ok) { + throw new Error(`${copy.media.manifestLoadFailed} (${response.status} at ${MEDIA_MANIFEST_URL})`); + } + + const payload = (await response.json()) as Partial; + return normalizeMediaManifest(payload); + } catch (error) { + if (error instanceof Error && error.name === 'AbortError') { + throw error; + } + throw new Error( + `${copy.media.manifestLoadFailed}: ${error instanceof Error ? error.message : String(error)} (URL: ${MEDIA_MANIFEST_URL})` + ); } - - const payload = (await response.json()) as Partial; - return normalizeMediaManifest(payload); }, }; diff --git a/src/entities/media/model/resolveMediaAsset.ts b/src/entities/media/model/resolveMediaAsset.ts index 96c41b6..bada8f8 100644 --- a/src/entities/media/model/resolveMediaAsset.ts +++ b/src/entities/media/model/resolveMediaAsset.ts @@ -99,18 +99,18 @@ const mergeSoundAssets = (manifest: MediaManifest) => { }; export const normalizeMediaManifest = (manifest: Partial | null | undefined): MediaManifest => { - const mergedManifest: MediaManifest = { + const baseManifest: MediaManifest = { version: manifest?.version ?? DEFAULT_MEDIA_MANIFEST.version, updatedAt: manifest?.updatedAt ?? DEFAULT_MEDIA_MANIFEST.updatedAt, cdnBaseUrl: manifest?.cdnBaseUrl ?? DEFAULT_MEDIA_MANIFEST.cdnBaseUrl, - scenes: manifest?.scenes ?? [], - sounds: manifest?.sounds ?? [], + scenes: manifest?.scenes ?? DEFAULT_MEDIA_MANIFEST.scenes, + sounds: manifest?.sounds ?? DEFAULT_MEDIA_MANIFEST.sounds, }; return { - ...mergedManifest, - scenes: mergeSceneAssets(mergedManifest), - sounds: mergeSoundAssets(mergedManifest), + ...baseManifest, + scenes: mergeSceneAssets(baseManifest), + sounds: mergeSoundAssets(baseManifest), }; }; diff --git a/src/entities/media/model/useMediaCatalog.ts b/src/entities/media/model/useMediaCatalog.ts index 290f83b..f79a9c4 100644 --- a/src/entities/media/model/useMediaCatalog.ts +++ b/src/entities/media/model/useMediaCatalog.ts @@ -40,10 +40,18 @@ const readMediaManifest = async (signal?: AbortSignal): Promise { - const nextError = error instanceof Error ? error.message : null; + // Only return abort errors up the chain if we're not using fallback + if (error instanceof Error && error.name === 'AbortError') { + throw error; + } + + const nextError = error instanceof Error ? error.message : String(error); + + // Explicitly use normalize with null to get a pure fallback manifest + const fallbackManifest = normalizeMediaManifest(null); return { - manifest: manifestCache, + manifest: fallbackManifest, error: nextError, usedFallbackManifest: true, };