feat: Implement EPUB asset fetching with improved error handling and status messaging

This commit is contained in:
JB
2025-10-13 13:42:13 -07:00
parent 0f549a56e4
commit b3dc73cb15
+53 -18
View File
@@ -287,6 +287,24 @@
return null; return null;
}; };
const fetchEpubAsset = async (url) => {
if (!url) {
throw new Error('Missing EPUB URL');
}
const response = await fetch(url, {
credentials: 'same-origin',
headers: {
Accept: 'application/epub+zip,application/octet-stream;q=0.8,*/*;q=0.5',
},
});
if (!response.ok) {
const error = new Error(`HTTP ${response.status}`);
error.status = response.status;
throw error;
}
return response.arrayBuffer();
};
const buildAssetUrl = (path) => { const buildAssetUrl = (path) => {
if (!path) { if (!path) {
return ''; return '';
@@ -812,27 +830,44 @@
} }
setStatus('Fetching EPUB…'); setStatus('Fetching EPUB…');
let epubPayload = null;
const fetchTimeout = setTimeout(() => {
setStatus('Still fetching EPUB… this may take a moment for large books.');
}, 4000);
try {
epubPayload = await fetchEpubAsset(epubUrl);
} catch (error) {
clearTimeout(fetchTimeout);
console.error('Failed to fetch EPUB payload', error);
if (error?.status === 404) {
setStatus('The EPUB package could not be found for this job.');
} else if (error?.status === 403) {
setStatus('Access to the EPUB package was denied. Check your session.');
} else {
setStatus('Unable to fetch the EPUB asset for this job.');
}
return;
}
clearTimeout(fetchTimeout);
book = window.ePub({ book = window.ePub({
replacements: 'view', replacements: 'view',
requestCredentials: 'same-origin', requestCredentials: 'same-origin',
}); });
const preloadTimeout = setTimeout(() => { setStatus('Loading book…');
setStatus('Still fetching EPUB… this may take a moment for large books.');
}, 4000);
try { try {
await book.open(epubUrl, 'epub'); await book.open(epubPayload, 'binary');
} catch (error) { } catch (error) {
console.error('Failed to fetch EPUB payload', error); console.error('Book failed to open binary payload', error);
clearTimeout(preloadTimeout); setStatus('Unable to open this EPUB.');
setStatus('Unable to fetch the EPUB asset for this job.');
return; return;
} }
clearTimeout(preloadTimeout);
setStatus('Loading book…');
rendition = book.renderTo('reader-view', { rendition = book.renderTo('reader-view', {
flow: 'scrolled-doc', flow: 'scrolled-doc',
width: '100%', width: '100%',
@@ -848,6 +883,14 @@
registerRenditionHooks(); registerRenditionHooks();
try {
await book.ready;
} catch (error) {
console.error('Book failed to initialize', error);
setStatus('Unable to open this EPUB.');
return;
}
let navigation = null; let navigation = null;
try { try {
navigation = await book.loaded.navigation; navigation = await book.loaded.navigation;
@@ -870,14 +913,6 @@
return; return;
} }
try {
await book.ready;
} catch (error) {
console.error('Book failed to initialize', error);
setStatus('Unable to open this EPUB.');
return;
}
rendition.on('relocated', (location) => { rendition.on('relocated', (location) => {
if (suppressRelocate || !location || !location.start) { if (suppressRelocate || !location || !location.start) {
return; return;