ComplianceViolationException.java
package com.cloudforgeci.api.deploy;
import com.cloudforgeci.api.core.rules.NagReportReader.ComplianceFinding;
import java.util.List;
/**
* Thrown by {@link CloudForgeSynthesizer#synthesize} when {@code complianceMode=enforce} and
* cdk-nag found at least one non-suppressed {@code ERROR}-level violation. This implements
* {@code ComplianceMode.ENFORCE}'s "blocks CDK synthesis" behavior (see {@link
* com.cloudforgeci.api.core.rules.NagReportReader} for how findings are collected).
*
* <p>A dedicated type so callers such as a deploy pipeline can distinguish a template compliance
* failure from an AWS communication error. Carries the structured findings so callers can render
* them without parsing the message.</p>
*/
public final class ComplianceViolationException extends RuntimeException {
private final transient List<ComplianceFinding> findings;
public ComplianceViolationException(String stackName, List<ComplianceFinding> findings) {
super(buildMessage(stackName, findings));
this.findings = List.copyOf(findings);
}
public List<ComplianceFinding> findings() {
return findings;
}
private static String buildMessage(String stackName, List<ComplianceFinding> findings) {
StringBuilder message = new StringBuilder("Compliance check failed for ")
.append(stackName)
.append(" (complianceMode=enforce) -- ")
.append(findings.size())
.append(findings.size() == 1 ? " violation" : " violations")
.append(":");
for (ComplianceFinding finding : findings) {
message.append("\n - ").append(finding.describe());
}
return message.toString();
}
}