diff --git a/korman/exporter/convert.py b/korman/exporter/convert.py index 81ffc08..36d424f 100644 --- a/korman/exporter/convert.py +++ b/korman/exporter/convert.py @@ -107,6 +107,11 @@ class Exporter: self.report.progress_end() self.report.save() + # Step 5.2: If any nonfatal errors were encountered during the export, we will + # raise them here, now that everything is finished, to draw attention + # to whatever the problem might be. + self.report.raise_errors() + def _bake_static_lighting(self): lighting_method = self._op.lighting_method if lighting_method != "skip": diff --git a/korman/exporter/explosions.py b/korman/exporter/explosions.py index 331c173..48151e3 100644 --- a/korman/exporter/explosions.py +++ b/korman/exporter/explosions.py @@ -13,6 +13,15 @@ # You should have received a copy of the GNU General Public License # along with Korman. If not, see . +class NonfatalExportError(Exception): + def __init__(self, *args, **kwargs): + assert args + if len(args) > 1: + super(Exception, self).__init__(args[0].format(*args[1:], **kwargs)) + else: + super(Exception, self).__init__(args[0]) + + class ExportError(Exception): def __init__(self, value="Undefined Export Error"): super(Exception, self).__init__(value) diff --git a/korman/exporter/logger.py b/korman/exporter/logger.py index 7d4e232..98f96ec 100644 --- a/korman/exporter/logger.py +++ b/korman/exporter/logger.py @@ -14,6 +14,7 @@ # along with Korman. If not, see . from ..korlib import ConsoleToggler +from .explosions import NonfatalExportError from pathlib import Path import threading import time @@ -24,6 +25,7 @@ _MAX_TIME_UNTIL_ELIPSES = 2.0 class _ExportLogger: def __init__(self, print_logs, age_path=None): + self._errors = [] self._porting = [] self._warnings = [] self._age_path = Path(age_path) if age_path is not None else None @@ -42,10 +44,23 @@ class _ExportLogger: def __exit__(self, type, value, traceback): if value is not None: - ConsoleToggler().keep_console = True + ConsoleToggler().keep_console = not isinstance(value, NonfatalExportError) self._file.close() return False + def error(self, *args, **kwargs): + assert args + indent = kwargs.get("indent", 0) + msg = "{}ERROR: {}".format(" " * indent, args[0]) + if len(args) > 1: + msg = msg.format(*args[1:], **kwargs) + if self._file is not None: + self._file.writelines((msg, "\n")) + if self._print_logs: + print(msg) + cache = args[0] if len(args) == 1 else args[0].format(*args[1:]) + self._errors.append(cache) + def msg(self, *args, **kwargs): assert args indent = kwargs.get("indent", 0) @@ -67,7 +82,8 @@ class _ExportLogger: self._file.writelines((msg, "\n")) if self._print_logs: print(msg) - self._porting.append(args[0]) + cache = args[0] if len(args) == 1 else args[0].format(*args[1:]) + self._porting.append(cache) def progress_add_step(self, name): @@ -92,6 +108,14 @@ class _ExportLogger: self.msg("Exporting '{}'", self._age_path.name) self._time_start_overall = time.perf_counter() + def raise_errors(self): + num_errors = len(self._errors) + if num_errors == 1: + raise NonfatalExportError(self._errors[0]) + elif num_errors: + raise NonfatalExportError("""{} errors were encountered during export. Check the export log for more details: + {}""", num_errors, self._file.name) + def save(self): # TODO pass @@ -106,7 +130,8 @@ class _ExportLogger: self._file.writelines((msg, "\n")) if self._print_logs: print(msg) - self._warnings.append(args[0]) + cache = args[0] if len(args) == 1 else args[0].format(*args[1:]) + self._warnings.append(cache) class ExportProgressLogger(_ExportLogger): diff --git a/korman/operators/op_export.py b/korman/operators/op_export.py index a1944d0..fa8040b 100644 --- a/korman/operators/op_export.py +++ b/korman/operators/op_export.py @@ -177,6 +177,9 @@ class PlasmaAgeExportOperator(ExportOperator, bpy.types.Operator): except exporter.ExportError as error: self.report({"ERROR"}, str(error)) return {"CANCELLED"} + except exporter.NonfatalExportError as error: + self.report({"ERROR"}, str(error)) + return {"FINISHED"} else: if self.profile_export: stats_out = path.with_name("{}_profile.log".format(ageName))