LibreChat/api/server/routes/files/images.js
Danny Avila 365a0dc0f6
🩺 refactor: Surface Descriptive OCR Error Messages to Client (#12344)
* fix: pass along error message when OCR fails

Right now, if OCR fails, it just says "Error processing file" which
isn't very helpful.

The `error.message` does has helpful information in it, but our
filter wasn't including the right case to pass it along. Now it does!

* fix: extract shared upload error filter, apply to images route

The 'Unable to extract text from' error was only allowlisted in the
files route but not the images route, which also calls
processAgentFileUpload. Extract the duplicated error filter logic
into a shared resolveUploadErrorMessage utility in packages/api so
both routes stay in sync.

---------

Co-authored-by: Dan Lew <daniel@mightyacorn.com>
2026-03-20 17:10:25 -04:00

69 lines
2 KiB
JavaScript

const path = require('path');
const fs = require('fs').promises;
const express = require('express');
const { logger } = require('@librechat/data-schemas');
const { verifyAgentUploadPermission, resolveUploadErrorMessage } = require('@librechat/api');
const { isAssistantsEndpoint } = require('librechat-data-provider');
const {
processAgentFileUpload,
processImageFile,
filterFile,
} = require('~/server/services/Files/process');
const { checkPermission } = require('~/server/services/PermissionService');
const { getAgent } = require('~/models/Agent');
const router = express.Router();
router.post('/', async (req, res) => {
const metadata = req.body;
const appConfig = req.config;
try {
filterFile({ req, image: true });
metadata.temp_file_id = metadata.file_id;
metadata.file_id = req.file_id;
if (!isAssistantsEndpoint(metadata.endpoint) && metadata.tool_resource != null) {
const denied = await verifyAgentUploadPermission({
req,
res,
metadata,
getAgent,
checkPermission,
});
if (denied) {
return;
}
return await processAgentFileUpload({ req, res, metadata });
}
await processImageFile({ req, res, metadata });
} catch (error) {
// TODO: delete remote file if it exists
logger.error('[/files/images] Error processing file:', error);
const message = resolveUploadErrorMessage(error);
try {
const filepath = path.join(
appConfig.paths.imageOutput,
req.user.id,
path.basename(req.file.filename),
);
await fs.unlink(filepath);
} catch (error) {
logger.error('[/files/images] Error deleting file:', error);
}
res.status(500).json({ message });
} finally {
try {
await fs.unlink(req.file.path);
logger.debug('[/files/images] Temp. image upload file deleted');
} catch {
logger.debug('[/files/images] Temp. image upload file already deleted');
}
}
});
module.exports = router;