@bestdefense/bd-agent
Version:
An AI-powered coding assistant CLI that connects to AWS Bedrock
130 lines • 5.77 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ToolExecutionError = exports.BedrockError = void 0;
exports.formatError = formatError;
exports.handleBedrockError = handleBedrockError;
exports.createRetryHandler = createRetryHandler;
const chalk_1 = __importDefault(require("chalk"));
class BedrockError extends Error {
code;
statusCode;
retryable;
constructor(message, code, statusCode, retryable = false) {
super(message);
this.code = code;
this.statusCode = statusCode;
this.retryable = retryable;
this.name = 'BedrockError';
}
}
exports.BedrockError = BedrockError;
class ToolExecutionError extends Error {
toolName;
originalError;
constructor(message, toolName, originalError) {
super(message);
this.toolName = toolName;
this.originalError = originalError;
this.name = 'ToolExecutionError';
}
}
exports.ToolExecutionError = ToolExecutionError;
function formatError(error) {
if (error instanceof BedrockError) {
let message = chalk_1.default.red(`❌ Bedrock Error: ${error.message}`);
if (error.code) {
message += chalk_1.default.gray(`\n Code: ${error.code}`);
}
if (error.statusCode) {
message += chalk_1.default.gray(`\n Status: ${error.statusCode}`);
}
if (error.retryable) {
message += chalk_1.default.yellow(`\n ⚠️ This error may be temporary. Please try again.`);
}
// Add helpful suggestions based on error type
if (error.code === 'CredentialsError' || error.message.includes('credential')) {
message += chalk_1.default.cyan(`\n 💡 Try running: bd-agent setup`);
}
else if (error.code === 'AccessDeniedException') {
message += chalk_1.default.cyan(`\n 💡 Check your AWS permissions for Bedrock access`);
}
else if (error.code === 'ModelNotFound') {
message += chalk_1.default.cyan(`\n 💡 Verify the model ID in your configuration`);
}
return message;
}
if (error instanceof ToolExecutionError) {
let message = chalk_1.default.red(`❌ Tool Error in ${error.toolName}: ${error.message}`);
if (error.originalError) {
message += chalk_1.default.gray(`\n Details: ${error.originalError.message || error.originalError}`);
}
// Add tool-specific suggestions
if (error.toolName === 'git_commit' && error.message.includes('nothing to commit')) {
message += chalk_1.default.cyan(`\n 💡 No changes detected. Make some changes first.`);
}
else if (error.toolName.includes('file') && error.message.includes('ENOENT')) {
message += chalk_1.default.cyan(`\n 💡 File not found. Check the file path.`);
}
else if (error.toolName === 'run_command' && error.message.includes('command not found')) {
message += chalk_1.default.cyan(`\n 💡 Command not found. Verify it's installed.`);
}
return message;
}
// Generic error formatting
if (error instanceof Error) {
let message = chalk_1.default.red(`❌ Error: ${error.message}`);
if (error.stack && process.env.DEBUG) {
message += chalk_1.default.gray(`\n\nStack trace:\n${error.stack}`);
}
return message;
}
// Fallback for non-Error objects
return chalk_1.default.red(`❌ Error: ${String(error)}`);
}
function handleBedrockError(error) {
// Map AWS SDK errors to our custom error type
if (error.name === 'CredentialsProviderError') {
return new BedrockError('Invalid or expired AWS credentials', 'CredentialsError', 401, false);
}
if (error.name === 'AccessDeniedException') {
return new BedrockError('Access denied to Bedrock. Check your IAM permissions.', 'AccessDeniedException', 403, false);
}
if (error.name === 'ResourceNotFoundException') {
return new BedrockError('Model not found. Verify the model ID.', 'ModelNotFound', 404, false);
}
if (error.name === 'ThrottlingException') {
return new BedrockError('Rate limit exceeded. Please wait before retrying.', 'RateLimitExceeded', 429, true);
}
if (error.name === 'ServiceUnavailableException') {
return new BedrockError('Bedrock service is temporarily unavailable.', 'ServiceUnavailable', 503, true);
}
// Generic bedrock error
return new BedrockError(error.message || 'Unknown Bedrock error', error.name, error.$metadata?.httpStatusCode, false);
}
function createRetryHandler(maxRetries = 3, baseDelay = 1000) {
return async function retry(fn, errorHandler) {
let lastError;
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
}
catch (error) {
lastError = error;
const handledError = errorHandler ? errorHandler(error) : error;
if (handledError instanceof BedrockError && !handledError.retryable) {
throw handledError;
}
if (attempt < maxRetries - 1) {
const delay = baseDelay * Math.pow(2, attempt);
console.log(chalk_1.default.yellow(`⏳ Retrying in ${delay}ms... (attempt ${attempt + 2}/${maxRetries})`));
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw lastError;
};
}
//# sourceMappingURL=error-handler.js.map