From cb610cfdef3909334c09c704befa2ed0221b51c9 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 (cherry picked from commit eb7324e7fc077cd3c18a629194069f6c29ca8b8e) --- src/ifcconvert/IfcConvert.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 51ce532fdd..ca88e0556d 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -295,6 +295,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"); @@ -438,6 +442,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; @@ -1027,6 +1032,11 @@ int main(int argc, char** argv) { successful = false; } + if (fail_on_error && logger.max_severity() >= ::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.print_performance_stats(); }