Skip to content

Commit 757ee3f

Browse files
weirdryclaude
andcommitted
fix: improve AWS SDK error handling in db-toolkit for better debugging v2.3.1
Enhanced error handling to properly display AWS SDK error details instead of generic "UnknownError" messages. This helps diagnose issues like missing SSM parameters, Secrets Manager secrets, or EC2 instances. Changes: - Extract and display AWS SDK error name and message - Show contextual information (parameter path, secret ARN, etc.) - Apply to getDatabaseInfo, getDatabasePassword, and getBastionInstanceId - Improve error messages in psql command handler Before: "UnknownError" After: "ParameterNotFound: <message>\n Parameter: /path/to/parameter" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent c25b02a commit 757ee3f

3 files changed

Lines changed: 54 additions & 25 deletions

File tree

packages/db-toolkit/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fiftyten/db-toolkit",
3-
"version": "2.3.0",
3+
"version": "2.3.1",
44
"description": "Complete database toolkit: connections, migration, and operations via AWS Session Manager",
55
"main": "index.js",
66
"bin": {
@@ -54,4 +54,4 @@
5454
"publishConfig": {
5555
"access": "public"
5656
}
57-
}
57+
}

packages/db-toolkit/src/database-connector.ts

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,10 @@ export class DatabaseConnector {
146146
});
147147

148148
if (!response.Reservations || response.Reservations.length === 0) {
149-
throw new Error(`No bastion host found for environment: ${environment}`);
149+
throw new Error(
150+
`No bastion host found for environment: ${environment}\n` +
151+
` Expected EC2 instance tag: indicator-bastion-${environment}-host`
152+
);
150153
}
151154

152155
const instance = response.Reservations[0].Instances?.[0];
@@ -182,18 +185,25 @@ export class DatabaseConnector {
182185
? `/indicator/indicator-api/${environment}/database-environment-variables`
183186
: `/indicator/${database}-api/${environment}/database-environment-variables`;
184187

185-
const response = await this.callWithMfaRetry(async () => {
186-
const command = new GetParameterCommand({
187-
Name: parameterName
188+
try {
189+
const response = await this.callWithMfaRetry(async () => {
190+
const command = new GetParameterCommand({
191+
Name: parameterName
192+
});
193+
return await this.ssmClient.send(command);
188194
});
189-
return await this.ssmClient.send(command);
190-
});
191195

192-
if (!response.Parameter || !response.Parameter.Value) {
193-
throw new Error(`Database info not found for ${database} in environment: ${environment}`);
194-
}
196+
if (!response.Parameter || !response.Parameter.Value) {
197+
throw new Error(`Database info not found for ${database} in environment: ${environment}`);
198+
}
195199

196-
return JSON.parse(response.Parameter.Value);
200+
return JSON.parse(response.Parameter.Value);
201+
} catch (error: any) {
202+
// Re-throw with AWS SDK error details
203+
const errorName = error.name || 'UnknownError';
204+
const errorMessage = error.message || String(error);
205+
throw new Error(`${errorName}: ${errorMessage}\n Parameter: ${parameterName}`);
206+
}
197207
}
198208

199209
/**
@@ -202,20 +212,27 @@ export class DatabaseConnector {
202212
async getDatabasePassword(environment: string, database: string = 'indicator'): Promise<string> {
203213
const dbInfo = await this.getDatabaseInfo(environment, database);
204214

205-
const command = new GetSecretValueCommand({
206-
SecretId: dbInfo.DATABASE_SECRET_ARN
207-
});
215+
try {
216+
const command = new GetSecretValueCommand({
217+
SecretId: dbInfo.DATABASE_SECRET_ARN
218+
});
208219

209-
const response = await this.callWithMfaRetry(async () => {
210-
return await this.secretsClient.send(command);
211-
});
220+
const response = await this.callWithMfaRetry(async () => {
221+
return await this.secretsClient.send(command);
222+
});
212223

213-
if (!response.SecretString) {
214-
throw new Error(`Database password not found in secret: ${dbInfo.DATABASE_SECRET_ARN}`);
215-
}
224+
if (!response.SecretString) {
225+
throw new Error(`Database password not found in secret: ${dbInfo.DATABASE_SECRET_ARN}`);
226+
}
216227

217-
const secretValue = JSON.parse(response.SecretString);
218-
return secretValue.password || secretValue.PASSWORD;
228+
const secretValue = JSON.parse(response.SecretString);
229+
return secretValue.password || secretValue.PASSWORD;
230+
} catch (error: any) {
231+
// Re-throw with AWS SDK error details
232+
const errorName = error.name || 'UnknownError';
233+
const errorMessage = error.message || String(error);
234+
throw new Error(`${errorName}: ${errorMessage}\n Secret ARN: ${dbInfo.DATABASE_SECRET_ARN}`);
235+
}
219236
}
220237

221238
/**
@@ -649,7 +666,13 @@ export class DatabaseConnector {
649666
});
650667

651668
} catch (error) {
652-
console.error(chalk.red('Error setting up database connection:'), error instanceof Error ? error.message : String(error));
669+
console.error(chalk.red('Error setting up database connection:'));
670+
if (error instanceof Error) {
671+
console.error(chalk.red('Message:'), error.message);
672+
console.error(chalk.red('Stack:'), error.stack);
673+
} else {
674+
console.error(chalk.red('Error:'), error);
675+
}
653676
throw error;
654677
}
655678
}

packages/db-toolkit/src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,13 @@ program
110110
const connector = new DatabaseConnector(options.region);
111111
await connector.connectWithPassword(environment, options.database, parseInt(options.port));
112112
} catch (error) {
113-
console.error(chalk.red('Error connecting to database:'), error instanceof Error ? error.message : String(error));
113+
console.error(chalk.red('Error connecting to database:'));
114+
if (error instanceof Error) {
115+
console.error(chalk.red('Message:'), error.message);
116+
console.error(chalk.red('Stack:'), error.stack);
117+
} else {
118+
console.error(chalk.red('Error:'), error);
119+
}
114120
process.exit(1);
115121
}
116122
});

0 commit comments

Comments
 (0)