fix: 매니페스트 로드 실패 시 로컬 자산으로 안전하게 대체되지 않는 버그 수정
- normalizeMediaManifest에서 빈 데이터 수신 시 DEFAULT_MEDIA_MANIFEST를 활용하도록 수정 - 매니페스트 로드 실패 시 상세 정보(URL, 상태 코드)를 에러 메시지에 포함 - useMediaCatalog에서 fetch 에러 발생 시 명시적으로 로컬 기반 매니페스트를 적용하도록 보강
This commit is contained in:
@@ -36,6 +36,7 @@ export const mediaManifestApi = {
|
||||
return DEFAULT_MEDIA_MANIFEST;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(MEDIA_MANIFEST_URL, {
|
||||
method: 'GET',
|
||||
cache: MEDIA_MANIFEST_FETCH_CACHE,
|
||||
@@ -43,10 +44,18 @@ export const mediaManifestApi = {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(copy.media.manifestLoadFailed);
|
||||
throw new Error(`${copy.media.manifestLoadFailed} (${response.status} at ${MEDIA_MANIFEST_URL})`);
|
||||
}
|
||||
|
||||
const payload = (await response.json()) as Partial<MediaManifest>;
|
||||
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})`
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -99,18 +99,18 @@ const mergeSoundAssets = (manifest: MediaManifest) => {
|
||||
};
|
||||
|
||||
export const normalizeMediaManifest = (manifest: Partial<MediaManifest> | 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),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -40,10 +40,18 @@ const readMediaManifest = async (signal?: AbortSignal): Promise<MediaCatalogLoad
|
||||
};
|
||||
})
|
||||
.catch((error) => {
|
||||
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,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user