ZIP extraction error handling (#4002) * Improve error handling in extractFileFromZipBuffer function * Add warning logging to NovelAI image upscaling

c218c1baeaa58025ce38f1abc0dec742b0156097

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
2 files changed, +51 -27Ignore whitespace
src/endpoints/novelai.js+3 -2
@@ -394,7 +394,8 @@ router.post('/generate-image', async (request, response) => {
394394 });
395395
396396 if (!upscaleResult.ok) {
397- throw new Error('NovelAI returned an error.');
397+ const text = await upscaleResult.text();
398+ throw new Error('NovelAI returned an error.', { cause: text });
398399 }
399400
400401 const upscaledArchiveBuffer = await upscaleResult.arrayBuffer();
@@ -408,7 +409,7 @@ router.post('/generate-image', async (request, response) => {
408409
409410 return response.send(upscaledBase64);
410411 } catch (error) {
411412 console.warn('NovelAI generated an image, but upscaling failed. Returning original image.', error);
412413 return response.send(originalBase64);
413414 }
414415 } catch (error) {
src/util.js+48 -25
@@ -207,35 +207,58 @@ export function formatBytes(bytes) {
207207 * @returns {Promise<Buffer|null>} Buffer containing the extracted file. Null if the file was not found.
208208 */
209209export async function extractFileFromZipBuffer(archiveBuffer, fileExtension) {
210- return await new Promise((resolve, reject) => yauzl.fromBuffer(Buffer.from(archiveBuffer), { lazyEntries: true }, (err, zipfile) => {
210+ return await new Promise((resolve) => {
211- if (err) reject(err);
211+ try {
212-
212+ yauzl.fromBuffer(Buffer.from(archiveBuffer), { lazyEntries: true }, (err, zipfile) => {
213- zipfile.readEntry();
213+ if (err) {
214- zipfile.on('entry', (entry) => {
214+ console.warn(`Error opening ZIP file: ${err.message}`);
215- if (entry.fileName.endsWith(fileExtension) && !entry.fileName.startsWith('__MACOSX')) {
215+ return resolve(null);
216- console.info(`Extracting ${entry.fileName}`);
216+ }
217- zipfile.openReadStream(entry, (err, readStream) => {
217+
218- if (err) {
218+ zipfile.readEntry();
219- reject(err);
219+
220- } else {
220+ zipfile.on('entry', (entry) => {
221- const chunks = [];
221+ if (entry.fileName.endsWith(fileExtension) && !entry.fileName.startsWith('__MACOSX')) {
222- readStream.on('data', (chunk) => {
222+ console.info(`Extracting ${entry.fileName}`);
223- chunks.push(chunk);
223+ zipfile.openReadStream(entry, (err, readStream) => {
224- });
224+ if (err) {
225+ console.warn(`Error opening read stream: ${err.message}`);
226+ return zipfile.readEntry();
227+ } else {
228+ const chunks = [];
229+ readStream.on('data', (chunk) => {
230+ chunks.push(chunk);
231+ });
232+
233+ readStream.on('end', () => {
234+ const buffer = Buffer.concat(chunks);
235+ resolve(buffer);
236+ zipfile.readEntry(); // Continue to the next entry
237+ });
225238
226239 readStream.on('enderror', (err) => {
227- const buffer = Buffer.concat(chunks);
240+ console.warn(`Error reading stream: ${err.message}`);
228- resolve(buffer);
241+ zipfile.readEntry();
229- zipfile.readEntry(); // Continue to the next entry
242+ });
243+ }
230244 });
245+ } else {
246+ zipfile.readEntry();
231247 }
232248 });
233- } else {
249+
234- zipfile.readEntry();
250+ zipfile.on('error', (err) => {
235- }
251+ console.warn('ZIP processing error', err);
236- });
252+ resolve(null);
237- zipfile.on('end', () => resolve(null));
253+ });
238- }));
254+
255+ zipfile.on('end', () => resolve(null));
256+ });
257+ } catch (error) {
258+ console.warn('Failed to process ZIP buffer', error);
259+ resolve(null);
260+ }
261+ });
239262}
240263
241264/**