mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab25c37dd3 | ||
|
|
463daf2ed0 | ||
|
|
af6ef53aed | ||
|
|
2ef9de8aa3 | ||
|
|
1d62f6264a | ||
|
|
6dc8b922f6 | ||
|
|
68abab9a90 |
@@ -11,7 +11,8 @@
|
||||
"Bash(npm test:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(npx tsc:*)",
|
||||
"Bash(sed:*)"
|
||||
"Bash(npm run build:*)"
|
||||
|
||||
],
|
||||
"deny": []
|
||||
}
|
||||
|
||||
Generated
+5
-4
@@ -39,7 +39,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.40.0",
|
||||
"@types/node": "^24.2.0",
|
||||
"@types/node": "^24.2.1",
|
||||
"@types/react": "^19.1.4",
|
||||
"@types/react-dom": "^19.1.5",
|
||||
"@vitejs/plugin-react": "^4.5.0",
|
||||
@@ -2386,10 +2386,11 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.0.tgz",
|
||||
"integrity": "sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==",
|
||||
"version": "24.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.1.tgz",
|
||||
"integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.10.0"
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.40.0",
|
||||
"@types/node": "^24.2.0",
|
||||
"@types/node": "^24.2.1",
|
||||
"@types/react": "^19.1.4",
|
||||
"@types/react-dom": "^19.1.5",
|
||||
"@vitejs/plugin-react": "^4.5.0",
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ConvertParameters } from './useConvertParameters';
|
||||
import { detectFileExtension } from '../../../utils/fileUtils';
|
||||
import { createFileFromApiResponse } from '../../../utils/fileResponseUtils';
|
||||
import { useToolOperation, ToolOperationConfig } from '../shared/useToolOperation';
|
||||
import { createStandardErrorHandler } from '../../../utils/toolErrorHandler';
|
||||
import { getEndpointUrl, isImageFormat, isWebFormat } from '../../../utils/convertUtils';
|
||||
|
||||
const shouldProcessFilesSeparately = (
|
||||
@@ -134,14 +135,6 @@ export const useConvertOperation = () => {
|
||||
buildFormData, // Not used with customProcessor but required
|
||||
filePrefix: 'converted_',
|
||||
customProcessor: customConvertProcessor, // Convert handles its own routing
|
||||
getErrorMessage: (error) => {
|
||||
if (error.response?.data && typeof error.response.data === 'string') {
|
||||
return error.response.data;
|
||||
}
|
||||
if (error.message) {
|
||||
return error.message;
|
||||
}
|
||||
return t("convert.errorConversion", "An error occurred while converting the file.");
|
||||
}
|
||||
getErrorMessage: createStandardErrorHandler(t('convert.errorConversion', 'An error occurred while converting the file.'))
|
||||
});
|
||||
};
|
||||
|
||||
@@ -103,10 +103,9 @@ export const useOCROperation = () => {
|
||||
filePrefix: 'ocr_',
|
||||
multiFileEndpoint: false, // Process files individually
|
||||
responseHandler, // use shared flow
|
||||
getErrorMessage: (error) =>
|
||||
error.message?.includes('OCR tools') && error.message?.includes('not installed')
|
||||
? 'OCR tools (OCRmyPDF or Tesseract) are not installed on the server. Use the standard or fat Docker image instead of ultra-lite, or install OCR tools manually.'
|
||||
: createStandardErrorHandler(t('ocr.error.failed', 'OCR operation failed'))(error),
|
||||
getErrorMessage: (error) => {
|
||||
return createStandardErrorHandler(t('ocr.error.failed', 'OCR operation failed'))(error);
|
||||
},
|
||||
};
|
||||
|
||||
return useToolOperation(ocrConfig);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useFileContext } from '../../../contexts/FileContext';
|
||||
import { useToolState, type ProcessingProgress } from './useToolState';
|
||||
import { useToolApiCalls, type ApiCallsConfig } from './useToolApiCalls';
|
||||
import { useToolResources } from './useToolResources';
|
||||
import { extractErrorMessage } from '../../../utils/toolErrorHandler';
|
||||
import { extractErrorMessage, type ToolError } from '../../../utils/toolErrorHandler';
|
||||
import { createOperation } from '../../../utils/toolOperationTracker';
|
||||
import { ResponseHandler } from '../../../utils/toolResponseProcessor';
|
||||
|
||||
@@ -60,7 +60,7 @@ export interface ToolOperationConfig<TParams = void> {
|
||||
customProcessor?: (params: TParams, files: File[]) => Promise<File[]>;
|
||||
|
||||
/** Extract user-friendly error messages from API errors */
|
||||
getErrorMessage?: (error: any) => string;
|
||||
getErrorMessage?: (error: unknown) => string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +204,7 @@ export const useToolOperation = <TParams = void>(
|
||||
markOperationApplied(fileId, operationId);
|
||||
}
|
||||
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
const errorMessage = config.getErrorMessage?.(error) || extractErrorMessage(error);
|
||||
actions.setError(errorMessage);
|
||||
actions.setStatus('');
|
||||
|
||||
@@ -2,16 +2,77 @@
|
||||
* Standardized error handling utilities for tool operations
|
||||
*/
|
||||
|
||||
/**
|
||||
* Standard error type that covers common error patterns
|
||||
*/
|
||||
export interface ToolError {
|
||||
message?: string;
|
||||
response?: {
|
||||
data?: string | unknown;
|
||||
status?: number;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract error message from JSON response data
|
||||
*/
|
||||
const extractFromJsonData = (data: unknown): string | null => {
|
||||
if (typeof data === 'object' && data !== null) {
|
||||
const obj = data as Record<string, unknown>;
|
||||
// Common JSON error patterns
|
||||
if (typeof obj.message === 'string' && obj.message.trim()) {
|
||||
return obj.message.trim();
|
||||
}
|
||||
if (typeof obj.error === 'string' && obj.error.trim()) {
|
||||
return obj.error.trim();
|
||||
}
|
||||
if (typeof obj.detail === 'string' && obj.detail.trim()) {
|
||||
return obj.detail.trim();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default error extractor that follows the standard pattern
|
||||
*/
|
||||
export const extractErrorMessage = (error: any): string => {
|
||||
if (error.response?.data && typeof error.response.data === 'string') {
|
||||
return error.response.data;
|
||||
export const extractErrorMessage = (error: unknown): string => {
|
||||
// Early return if error is null/undefined
|
||||
if (!error || (typeof error !== 'object')) {
|
||||
return 'Operation failed';
|
||||
}
|
||||
if (error.message) {
|
||||
return error.message;
|
||||
|
||||
const typedError = error as ToolError;
|
||||
|
||||
// Try response.data first
|
||||
if (typedError.response?.data) {
|
||||
// Handle string response.data
|
||||
if (typeof typedError.response.data === 'string' && typedError.response.data.trim()) {
|
||||
return typedError.response.data.trim();
|
||||
}
|
||||
|
||||
// Handle JSON response.data
|
||||
const jsonMessage = extractFromJsonData(typedError.response.data);
|
||||
if (jsonMessage) {
|
||||
return jsonMessage;
|
||||
}
|
||||
|
||||
// Handle Blob or other non-string data gracefully
|
||||
if (typedError.response.data instanceof Blob) {
|
||||
return 'Server returned an error response';
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to error.message
|
||||
if (typedError.message && typedError.message.trim()) {
|
||||
return typedError.message.trim();
|
||||
}
|
||||
|
||||
// Add HTTP status context if available
|
||||
if (typedError.response?.status) {
|
||||
return `Server error (${typedError.response.status})`;
|
||||
}
|
||||
|
||||
return 'Operation failed';
|
||||
};
|
||||
|
||||
@@ -21,13 +82,9 @@ export const extractErrorMessage = (error: any): string => {
|
||||
* @returns Error handler function that follows the standard pattern
|
||||
*/
|
||||
export const createStandardErrorHandler = (fallbackMessage: string) => {
|
||||
return (error: any): string => {
|
||||
if (error.response?.data && typeof error.response.data === 'string') {
|
||||
return error.response.data;
|
||||
}
|
||||
if (error.message) {
|
||||
return error.message;
|
||||
}
|
||||
return fallbackMessage;
|
||||
return (error: unknown): string => {
|
||||
const message = extractErrorMessage(error);
|
||||
return message === 'Operation failed' ? fallbackMessage : message;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
"lib": ["es2022", "dom", "dom.iterable"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
"jsx": "react-jsx", /* Specify what JSX code is generated. */
|
||||
// "libReplacement": true, /* Enable lib replacement. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
|
||||
Reference in New Issue
Block a user