From eb7324e7fc077cd3c18a629194069f6c29ca8b8e Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Fri, 10 Jul 2026 20:38:15 +0300 Subject: [PATCH] IfcConvert: add --fail-on-error to exit non-zero when conversion logs errors (#1118) IfcConvert returned a success exit code even when geometry conversion logged errors and silently dropped elements (for example a failed TopoDS::Shell build under layerset slicing produced valid looking output with most objects missing), so CI and scripts could not detect a partial conversion. Add an opt-in --fail-on-error flag that makes IfcConvert exit non-zero when any error was logged during processing, reusing the existing MaxSeverity based failure check already used for --validate. The default exit behaviour is unchanged, so pipelines that tolerate individual element failures are unaffected. Co-Authored-By: Claude Opus 4.8 --- src/ifcconvert/IfcConvert.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index acd5421638..38d245757c 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -252,6 +252,10 @@ int main(int argc, char** argv) { ("stderr-progress", "output progress to stderr stream") ("yes,y", "answer 'yes' automatically to possible confirmation queries (e.g. overwriting an existing output file)") ("no-progress", "suppress possible progress bar type of prints that use carriage return") + ("fail-on-error", "return a non-zero exit code when one or more errors were logged during " + "geometry conversion (e.g. an element failed to convert). By default IfcConvert exits " + "successfully as long as an output file could be written, even if some elements were " + "silently dropped. Enable this flag so scripts and CI can detect partial conversions.") ("log-format", po::value(&log_format), "log format: plain or json") ("log-file", new po::typed_value(&log_file), "redirect log output to file"); @@ -449,6 +453,7 @@ int main(int argc, char** argv) { const bool mmap = vmap.count("mmap") != 0; const bool no_progress = vmap.count("no-progress") != 0; + const bool fail_on_error = vmap.count("fail-on-error") != 0; const bool quiet = vmap.count("quiet") != 0; const bool stderr_progress = vmap.count("stderr-progress") != 0; @@ -1220,6 +1225,11 @@ int main(int argc, char** argv) { successful = false; } + if (fail_on_error && logger.MaxSeverity() >= Logger::LOG_ERROR) { + logger.Error("SYS", 26, "Errors encountered during processing, failing due to --fail-on-error."); + successful = false; + } + if (logger.Verbosity() == Logger::LOG_PERF) { logger.PrintPerformanceStats(); }