Stirling-Tools/Stirling-PDF · error · Error
${operationName} operation failed: ${error.response?.data ||
Error message
${operationName} operation failed: ${error.response?.data || error.message} What it means
A catch-all wrapper thrown by executeToolOperationWithPrefix when any error escapes the tool execution body (single-file, multi-file, or customProcessor path). It re-throws with the operationName prefixed and the underlying cause attached via { cause: error }, preferring error.response?.data (Axios-style backend error body) over error.message. This is the error a caller of the executor actually sees for any backend or processing failure.
Source
Thrown at frontend/editor/src/core/utils/automationExecutor.ts:207
// Execute based on tool type
if (config.toolType === ToolType.multiFile) {
return await executeMultiFileOperation(
config,
mergedParameters,
files,
filePrefix,
);
} else {
return await executeSingleFileOperation(
config,
mergedParameters,
files,
filePrefix,
);
}
} catch (error: any) {
console.error(`❌ ${operationName} failed:`, error);
throw new Error(
`${operationName} operation failed: ${error.response?.data || error.message}`,
{
cause: error,
},
);
}
};
/**
* Execute an entire automation sequence
*/
export const executeAutomationSequence = async (
automation: any,
initialFiles: File[],
toolRegistry: ToolRegistry,
onStepStart?: (stepIndex: number, operationName: string) => void,
onStepComplete?: (stepIndex: number, resultFiles: File[]) => void,
onStepError?: (stepIndex: number, error: string) => void,View on GitHub (pinned to 9ef20dcab8)
Solutions
- Inspect error.cause for the original error object; the wrapper preserves it.
- If error.response.data is present, read the backend's message — it usually pinpoints the bad parameter or file.
- Check browser DevTools Network tab for the failing POST to see status code and response body.
- If it is a transient network/timeout issue, consider retrying with backoff for idempotent operations.
- Validate file types and parameters against the tool's requirements before submitting.
Example fix
// before — caller does not inspect cause
catch (e) { show(e.message); }
// after — unwrap the real error
catch (e) {
const detail = e.cause?.response?.data ?? e.cause?.message ?? e.message;
show(`${operationName} failed: ${detail}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: ensure files are non-empty and of expected type before submitting.
function validateToolInputs(op: string, params: any, files: File[]): string | null {
if (!files.length) return 'No files provided.';
if (files.some(f => f.size === 0)) return 'One or more files are empty.';
return null;
}
const issue = validateToolInputs(op, params, files);
if (issue) { showUser(issue); return; } Type guard
function isAxiosError(e: unknown): e is { response?: { status: number; data: any }; message: string } {
return !!e && typeof e === 'object' && 'response' in e;
} Try / catch
try {
await executeToolOperation(op, params, files, registry);
} catch (e) {
const err = e as Error & { cause?: any };
const cause = err.cause;
const detail = cause?.response?.data ?? cause?.message ?? err.message;
const status = cause?.response?.status;
if (status === 401 || status === 403) showUser('Session expired. Please log in again.');
else if (status && status >= 500) showUser('Server error. Please try again later.');
else showUser(`${op} failed: ${detail}`);
} Prevention
- Always read error.cause for the underlying error object.
- Validate file types and sizes before submission to avoid backend 400s.
- Handle 401/403 specifically with a re-auth prompt.
- For idempotent operations, implement a bounded retry on network/5xx errors.
When it happens
Trigger: The backend POST returns a non-2xx (Axios rejects, error.response.data holds the server message). A network failure or timeout occurs (no response object, message is the network error). A customProcessor throws synchronously or its internal processing rejects. The processMultiFileResponse/zip extraction step fails downstream.
Common situations: Backend is down or the endpoint returned 400/500 (e.g. malformed params, unsupported file type, server exception). The user's session expired and the API returned 401/403. A large file caused a gateway timeout. The backend PDF operation threw because the input file was corrupt or password-protected.
Related errors
- Missing stored file ID in response.
- No automation configuration provided
- Automation step ${stepIndex + 1} failed: ${error}
- OCR service error: ${title}
- Response is not a valid PDF. Header: "${head}"
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/fd7896b490c1d8e9.
Report an issue: GitHub.