@@ -307,6 +307,116 @@ describe("Toolkit loading", () => {
307307
308308 expect ( lines ) . toEqual ( [ "CREATE_COMPLETE | AWS::IAM::Role" ] ) ;
309309 } ) ;
310+
311+ test ( "reports a resource failure when Toolkit only throws NoStack after rollback" , async ( ) => {
312+ const { loaded } = loadedToolkit ( ) ;
313+ const reason = "Agent with agentId: staging-agent not found" ;
314+ const runner = createCdkRunner ( createSilentLogger ( ) , async ( ioHost ) => {
315+ loaded . toolkit . deploy = async ( ) => {
316+ for ( const event of [
317+ {
318+ ResourceType : "AWS::IAM::Role" ,
319+ LogicalResourceId : "RuntimeRole" ,
320+ ResourceStatus : "CREATE_FAILED" ,
321+ ResourceStatusReason : "Resource creation cancelled" ,
322+ } ,
323+ {
324+ ResourceType : "AWS::BedrockAgentCore::RuntimeEndpoint" ,
325+ LogicalResourceId : "RuntimeEndpointProd" ,
326+ ResourceStatus : "CREATE_FAILED" ,
327+ ResourceStatusReason : reason ,
328+ } ,
329+ {
330+ ResourceType : "AWS::CloudFormation::Stack" ,
331+ LogicalResourceId : "AgentCore-orders-staging" ,
332+ ResourceStatus : "CREATE_FAILED" ,
333+ ResourceStatusReason : "The following resource(s) failed" ,
334+ } ,
335+ ] ) {
336+ await ioHost . notify ( {
337+ ...message ( "rollback progress" ) ,
338+ code : "CDK_TOOLKIT_I5502" ,
339+ data : { event } ,
340+ } ) ;
341+ }
342+ const error = new Error ( "CloudFormationStack object does not hold a stack" ) ;
343+ error . name = "NoStack" ;
344+ throw error ;
345+ } ;
346+ return loaded ;
347+ } ) ;
348+
349+ await expect (
350+ runner ( { kind : "deploy" , stackArtifactId : "AgentCore-orders-staging" } , runOptions ( ) ) ,
351+ ) . rejects . toThrow (
352+ `CloudFormationStack object does not hold a stack\n\n` +
353+ `CloudFormation failure: RuntimeEndpointProd (CREATE_FAILED): ${ reason } ` ,
354+ ) ;
355+ } ) ;
356+
357+ test ( "reports a bootstrap resource failure when Toolkit throws NoStack" , async ( ) => {
358+ const { loaded } = loadedToolkit ( ) ;
359+ const reason = "Bootstrap bucket could not be created" ;
360+ const runner = createCdkRunner ( createSilentLogger ( ) , async ( ioHost ) => {
361+ loaded . toolkit . bootstrap = async ( ) => {
362+ await ioHost . notify ( {
363+ ...message ( "bootstrap rollback progress" ) ,
364+ action : "bootstrap" ,
365+ code : "CDK_TOOLKIT_I5502" ,
366+ data : {
367+ event : {
368+ ResourceType : "AWS::S3::Bucket" ,
369+ LogicalResourceId : "StagingBucket" ,
370+ ResourceStatus : "CREATE_FAILED" ,
371+ ResourceStatusReason : reason ,
372+ } ,
373+ } ,
374+ } ) ;
375+ const error = new Error ( "CloudFormationStack object does not hold a stack" ) ;
376+ error . name = "NoStack" ;
377+ throw error ;
378+ } ;
379+ return loaded ;
380+ } ) ;
381+
382+ await expect (
383+ runner ( { kind : "bootstrap" , environments : [ "aws://111122223333/us-east-1" ] } , runOptions ( ) ) ,
384+ ) . rejects . toThrow (
385+ `CloudFormationStack object does not hold a stack\n\n` +
386+ `CloudFormation failure: StagingBucket (CREATE_FAILED): ${ reason } ` ,
387+ ) ;
388+ } ) ;
389+
390+ test ( "does not repeat a resource failure already diagnosed by Toolkit" , async ( ) => {
391+ const { loaded } = loadedToolkit ( ) ;
392+ const reason = `The resource failed: ${ "validation error " . repeat ( 12 ) } ` ;
393+ const original = new Error (
394+ `The stack failed to deploy:\n ${ reason . slice ( 0 , 120 ) } \n ${ reason . slice ( 120 ) } ` ,
395+ ) ;
396+ const runner = createCdkRunner ( createSilentLogger ( ) , async ( ioHost ) => {
397+ loaded . toolkit . deploy = async ( ) => {
398+ await ioHost . notify ( {
399+ ...message ( "update failed" ) ,
400+ code : "CDK_TOOLKIT_I5502" ,
401+ data : {
402+ event : {
403+ ResourceType : "AWS::BedrockAgentCore::RuntimeEndpoint" ,
404+ LogicalResourceId : "RuntimeEndpointProd" ,
405+ ResourceStatus : "UPDATE_FAILED" ,
406+ ResourceStatusReason : reason ,
407+ } ,
408+ } ,
409+ } ) ;
410+ throw original ;
411+ } ;
412+ return loaded ;
413+ } ) ;
414+
415+ await expect (
416+ runner ( { kind : "deploy" , stackArtifactId : "AgentCore-orders-staging" } , runOptions ( ) ) ,
417+ ) . rejects . toBe ( original ) ;
418+ expect ( original . message ) . not . toContain ( "CloudFormation failure:" ) ;
419+ } ) ;
310420} ) ;
311421
312422describe ( "bootstrap template loading" , ( ) => {
0 commit comments