DatabaseAuditFailure.java
package io.github.databaseaudits.spring.boot.assertion;
import java.util.List;
import java.util.stream.Collectors;
import io.github.databaseaudits.audit.finding.Finding;
import io.github.databaseaudits.platform.DatabasePlatform;
/**
* The {@link AssertionError} an audit assertion throws when its audit finds
* violations, carrying the structured {@link Finding}s behind the failure so a
* run-wide listener can render a consolidated report and precise fixes. Being an
* {@code AssertionError} keeps a finding a test <em>failure</em> rather than an
* error; the core audits' {@link IllegalStateException} (vacuous capture,
* unsupported platform) still surfaces cannot-run conditions as errors.
*
* <p>
* The {@linkplain #getMessage() message} is unchanged from the plain assertion
* this replaces — the curated {@code header}, then each finding's
* {@link Finding#description() description}, one per line — so existing console
* output and the {@link DatabaseAuditAssertions} facade's message aggregation are
* preserved.
*/
public final class DatabaseAuditFailure extends AssertionError {
private static final long serialVersionUID = 1L;
private final AuditFamily family;
private final String auditName;
private final String header;
private final List<Finding> findings;
private final DatabasePlatform platform;
/**
* Constructs a failure for one audit's violations.
*
* @param family
* the audit family that failed.
* @param auditName
* the audit's name — its core {@code *Audit} class simple
* name — a stable label the report groups findings by.
* @param header
* the curated, fix-oriented description of the violation.
* @param findings
* the structured findings behind the failure; must be
* non-empty.
* @param platform
* the database platform the audit ran against, so a fix
* renderer can emit dialect-correct DDL.
*/
public DatabaseAuditFailure(final AuditFamily family, final String auditName,
final String header, final List<? extends Finding> findings,
final DatabasePlatform platform) {
super(header + System.lineSeparator()
+ findings.stream().map(Finding::description)
.collect(Collectors.joining(System.lineSeparator())));
this.family = family;
this.auditName = auditName;
this.header = header;
this.findings = List.copyOf(findings);
this.platform = platform;
}
/**
* Returns the audit family that failed.
*
* @return the audit family.
*/
public AuditFamily family() {
return family;
}
/**
* Returns the audit's name — its core {@code *Audit} class simple name.
*
* @return the audit name.
*/
public String auditName() {
return auditName;
}
/**
* Returns the curated, fix-oriented header describing the violation.
*
* @return the failure header.
*/
public String header() {
return header;
}
/**
* Returns the structured findings behind this failure.
*
* @return the findings.
*/
public List<Finding> findings() {
return findings;
}
/**
* Returns the database platform the audit ran against.
*
* @return the database platform.
*/
public DatabasePlatform platform() {
return platform;
}
}