Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 11x 6x 5x 4x 1x 6x | /**
* Shared error handling utilities for MCP tool handlers.
*
* ISMS Policy: SC-002 (Input Validation), AC-003 (Least Privilege)
*/
import type { ToolResult } from './types.js';
import { buildErrorResponse } from './responseBuilder.js';
import { ToolError } from './errors.js';
/**
* Handle a caught tool error, returning a safe MCP error response.
* Never exposes raw stack traces to MCP clients.
*
* If the error is a {@link ToolError}, its own `toolName` and `isRetryable` are
* used so the originating tool and retryability are correctly surfaced to callers
* even when the error crosses handler boundaries.
*
* @param error - Caught error value
* @param toolName - Fallback tool name when error carries no tool identity
* @returns MCP-compliant ToolResult with isError flag set
*/
export function handleToolError(error: unknown, toolName: string): ToolResult {
if (error instanceof ToolError) {
return {
content: [{
type: 'text',
text: JSON.stringify({ error: error.message, toolName: error.toolName, retryable: error.isRetryable }, null, 2)
}],
isError: true
};
}
if (error instanceof Error) {
return buildErrorResponse(error, toolName);
}
return buildErrorResponse(new Error('Unknown error occurred'), toolName);
}
/**
* Build a structured data-unavailable response for tools that cannot
* compute meaningful results due to missing upstream data.
*
* @param toolName - Name of the tool reporting unavailability
* @param message - Human-readable explanation of why data is unavailable
* @returns MCP-compliant ToolResult
*/
export function handleDataUnavailable(toolName: string, message: string): ToolResult {
return {
content: [{
type: 'text',
text: JSON.stringify({
dataAvailable: false,
confidenceLevel: 'LOW',
toolName,
message
}, null, 2)
}]
};
}
|