Skip to content

Commit 3aa7ffc

Browse files
committed
Add enhanced error reporting using DescribeEventsCommand with change set ID and failed events filter
1 parent 803b08a commit 3aa7ffc

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

dist/index.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50144,8 +50144,8 @@ const core = __importStar(__nccwpck_require__(7484));
5014450144
const client_cloudformation_1 = __nccwpck_require__(3805);
5014550145
function waitUntilStackOperationComplete(params, input) {
5014650146
return __awaiter(this, void 0, void 0, function* () {
50147-
var _a;
50148-
const { client, maxWaitTime, minDelay } = params;
50147+
var _a, _b;
50148+
const { client, maxWaitTime, minDelay, changeSetId } = params;
5014950149
const startTime = Date.now();
5015050150
while (Date.now() - startTime < maxWaitTime * 1000) {
5015150151
try {
@@ -50173,7 +50173,25 @@ function waitUntilStackOperationComplete(params, input) {
5017350173
status === 'UPDATE_ROLLBACK_FAILED' ||
5017450174
status === 'IMPORT_ROLLBACK_COMPLETE' ||
5017550175
status === 'IMPORT_ROLLBACK_FAILED') {
50176-
throw new Error(`Stack operation failed with status: ${status}`);
50176+
// Get failed events using change set ID if available
50177+
let failureReason = `Stack operation failed with status: ${status}`;
50178+
if (changeSetId) {
50179+
try {
50180+
const events = yield client.send(new client_cloudformation_1.DescribeEventsCommand({
50181+
ChangeSetName: changeSetId,
50182+
Filters: { FailedEvents: true }
50183+
}));
50184+
const failedEvents = (_b = events.OperationEvents) === null || _b === void 0 ? void 0 : _b.filter(event => event.ResourceStatusReason);
50185+
if (failedEvents && failedEvents.length > 0) {
50186+
const reasons = failedEvents.map(event => `${event.LogicalResourceId}: ${event.ResourceStatusReason}`).join('; ');
50187+
failureReason += `. Failed resources: ${reasons}`;
50188+
}
50189+
}
50190+
catch (_c) {
50191+
// Ignore errors getting events
50192+
}
50193+
}
50194+
throw new Error(failureReason);
5017750195
}
5017850196
// In-progress states - keep waiting
5017950197
core.info(`Stack still in progress, waiting ${minDelay} seconds...`);
@@ -50313,7 +50331,7 @@ function updateStack(cfn, stack, params, failOnEmptyChangeSet, noExecuteChangeSe
5031350331
StackName: params.StackName
5031450332
}));
5031550333
core.debug('Updating CloudFormation stack');
50316-
yield waitUntilStackOperationComplete({ client: cfn, maxWaitTime: 43200, minDelay: 10 }, {
50334+
yield waitUntilStackOperationComplete({ client: cfn, maxWaitTime: 43200, minDelay: 10, changeSetId: params.ChangeSetName }, {
5031750335
StackName: params.StackName
5031850336
});
5031950337
return { stackId: stack.StackId };

src/deploy.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
CreateChangeSetCommand,
99
ExecuteChangeSetCommand,
1010
DescribeStacksCommand,
11+
DescribeEventsCommand,
1112
CloudFormationServiceException
1213
} from '@aws-sdk/client-cloudformation'
1314
import { CreateChangeSetInput, CreateStackInputWithName } from './main'
@@ -25,10 +26,11 @@ async function waitUntilStackOperationComplete(
2526
client: CloudFormationClient
2627
maxWaitTime: number
2728
minDelay: number
29+
changeSetId?: string
2830
},
2931
input: { StackName: string }
3032
): Promise<void> {
31-
const { client, maxWaitTime, minDelay } = params
33+
const { client, maxWaitTime, minDelay, changeSetId } = params
3234
const startTime = Date.now()
3335

3436
while (Date.now() - startTime < maxWaitTime * 1000) {
@@ -65,7 +67,26 @@ async function waitUntilStackOperationComplete(
6567
status === 'IMPORT_ROLLBACK_COMPLETE' ||
6668
status === 'IMPORT_ROLLBACK_FAILED'
6769
) {
68-
throw new Error(`Stack operation failed with status: ${status}`)
70+
// Get failed events using change set ID if available
71+
let failureReason = `Stack operation failed with status: ${status}`
72+
if (changeSetId) {
73+
try {
74+
const events = await client.send(new DescribeEventsCommand({
75+
ChangeSetName: changeSetId,
76+
Filters: { FailedEvents: true }
77+
}))
78+
const failedEvents = events.OperationEvents?.filter(event => event.ResourceStatusReason)
79+
if (failedEvents && failedEvents.length > 0) {
80+
const reasons = failedEvents.map(event =>
81+
`${event.LogicalResourceId}: ${event.ResourceStatusReason}`
82+
).join('; ')
83+
failureReason += `. Failed resources: ${reasons}`
84+
}
85+
} catch {
86+
// Ignore errors getting events
87+
}
88+
}
89+
throw new Error(failureReason)
6990
}
7091

7192
// In-progress states - keep waiting
@@ -283,7 +304,7 @@ export async function updateStack(
283304

284305
core.debug('Updating CloudFormation stack')
285306
await waitUntilStackOperationComplete(
286-
{ client: cfn, maxWaitTime: 43200, minDelay: 10 },
307+
{ client: cfn, maxWaitTime: 43200, minDelay: 10, changeSetId: params.ChangeSetName },
287308
{
288309
StackName: params.StackName!
289310
}

0 commit comments

Comments
 (0)