diff --git a/src/endpoints/vectors.js b/src/endpoints/vectors.js index e117dd6bb..7b089cd79 100644 --- a/src/endpoints/vectors.js +++ b/src/endpoints/vectors.js @@ -304,6 +304,35 @@ function getSourceSettings(source, request) { } } +/** + * Performs a request to regenerate the index if it is corrupted. + * @param {import('express').Request} req Express request object + * @param {import('express').Response} res Express response object + * @param {Error} error Error object + * @returns {Promise} Promise + */ +async function regenerateCorruptedIndexErrorHandler(req, res, error) { + if (error instanceof SyntaxError && !req.query.regenerated) { + const collectionId = String(req.body.collectionId); + const source = String(req.body.source) || 'transformers'; + + if (collectionId && source) { + const index = await getIndex(req.user.directories, collectionId, source, false); + const exists = await index.isIndexCreated(); + + if (exists) { + const path = index.folderPath; + console.error(`Corrupted index detected at ${path}, regenerating...`); + await index.deleteIndex(); + return res.redirect(307, req.originalUrl + '?regenerated=true'); + } + } + } + + console.error(error); + return res.sendStatus(500); +} + const router = express.Router(); router.post('/query', jsonParser, async (req, res) => { @@ -322,8 +351,7 @@ router.post('/query', jsonParser, async (req, res) => { const results = await queryCollection(req.user.directories, collectionId, source, sourceSettings, searchText, topK, threshold); return res.json(results); } catch (error) { - console.error(error); - return res.sendStatus(500); + return regenerateCorruptedIndexErrorHandler(req, res, error); } }); @@ -343,8 +371,7 @@ router.post('/query-multi', jsonParser, async (req, res) => { const results = await multiQueryCollection(req.user.directories, collectionIds, source, sourceSettings, searchText, topK, threshold); return res.json(results); } catch (error) { - console.error(error); - return res.sendStatus(500); + return regenerateCorruptedIndexErrorHandler(req, res, error); } }); @@ -362,8 +389,7 @@ router.post('/insert', jsonParser, async (req, res) => { await insertVectorItems(req.user.directories, collectionId, source, sourceSettings, items); return res.sendStatus(200); } catch (error) { - console.error(error); - return res.sendStatus(500); + return regenerateCorruptedIndexErrorHandler(req, res, error); } }); @@ -379,8 +405,7 @@ router.post('/list', jsonParser, async (req, res) => { const hashes = await getSavedHashes(req.user.directories, collectionId, source); return res.json(hashes); } catch (error) { - console.error(error); - return res.sendStatus(500); + return regenerateCorruptedIndexErrorHandler(req, res, error); } }); @@ -397,8 +422,7 @@ router.post('/delete', jsonParser, async (req, res) => { await deleteVectorItems(req.user.directories, collectionId, source, hashes); return res.sendStatus(200); } catch (error) { - console.error(error); - return res.sendStatus(500); + return regenerateCorruptedIndexErrorHandler(req, res, error); } });