diff --git a/client/ayon_houdini/api/lib.py b/client/ayon_houdini/api/lib.py index 98eb1dcbd6..816b4a4ae3 100644 --- a/client/ayon_houdini/api/lib.py +++ b/client/ayon_houdini/api/lib.py @@ -289,11 +289,9 @@ def render_rop(ropnode, frame_range=None): # The hou.Error is not inherited from a Python Exception class, # so we explicitly capture the houdini error, otherwise pyblish # will remain hanging. - raise PublishError( - "Render failed or interrupted", - description=f"An Error occurred while rendering {ropnode.path()}", - detail=f"{exc}" - ) + import traceback + traceback.print_exc() + raise RuntimeError("Render failed: {0}".format(exc)) def imprint(node, data, update=False): @@ -676,8 +674,7 @@ def get_top_referenced_parm(parm): def evalParmNoFrame(node, parm, pad_character="#"): parameter = node.parm(parm) - if not parameter: - raise PublishError(f"Parameter does not exist: {node}.{parm}") + assert parameter, "Parameter does not exist: %s.%s" % (node, parm) # If the parameter has a parameter reference, then get that # parameter instead as otherwise `unexpandedString()` fails. @@ -687,10 +684,8 @@ def evalParmNoFrame(node, parm, pad_character="#"): try: raw = parameter.unexpandedString() except hou.Error as exc: - raise PublishError( - f"Failed: {parameter}", - detail=f"{exc}" - ) + print("Failed: %s" % parameter) + raise RuntimeError(exc) def replace(match): padding = 1 diff --git a/client/ayon_houdini/plugins/publish/collect_arnold_rop.py b/client/ayon_houdini/plugins/publish/collect_arnold_rop.py index f8a605ab02..79361da420 100644 --- a/client/ayon_houdini/plugins/publish/collect_arnold_rop.py +++ b/client/ayon_houdini/plugins/publish/collect_arnold_rop.py @@ -4,6 +4,7 @@ import hou import pyblish.api +from ayon_core.pipeline import PublishError from ayon_houdini.api import plugin from ayon_houdini.api.lib import evalParmNoFrame @@ -28,13 +29,13 @@ def process(self, instance): rop = hou.node(instance.data.get("instance_node")) - default_prefix = evalParmNoFrame(rop, "ar_picture") + default_prefix = self.evalParmNoFrame(rop, "ar_picture") render_products = [] export_prefix = None export_products = [] if instance.data["splitRender"]: - export_prefix = evalParmNoFrame( + export_prefix = self.evalParmNoFrame( rop, "ar_ass_file", pad_character="0" ) beauty_export_product = self.get_render_product_name( @@ -74,7 +75,7 @@ def process(self, instance): if rop.evalParm("ar_aov_exr_enable_layer_name{}".format(index)): label = rop.evalParm("ar_aov_exr_layer_name{}".format(index)) else: - label = evalParmNoFrame(rop, "ar_aov_label{}".format(index)) + label = self.evalParmNoFrame(rop, "ar_aov_label{}".format(index)) # NOTE: # we don't collect the actual AOV path but rather assume @@ -160,3 +161,12 @@ def replace(match): os.path.join(dir, (file % i)).replace("\\", "/")) return expected_files + + def evalParmNoFrame(self, rop, parm, **kwargs): + try: + return evalParmNoFrame(rop, parm, **kwargs) + except Exception as exc: + raise PublishError( + f"Failed evaluating parameter '{parm}' on Rop node: {rop.path()}", + detail=f"{exc}" + ) \ No newline at end of file diff --git a/client/ayon_houdini/plugins/publish/collect_karma_rop.py b/client/ayon_houdini/plugins/publish/collect_karma_rop.py index 5ae898adae..7fbbd24f09 100644 --- a/client/ayon_houdini/plugins/publish/collect_karma_rop.py +++ b/client/ayon_houdini/plugins/publish/collect_karma_rop.py @@ -4,6 +4,7 @@ import hou import pyblish.api +from ayon_core.pipeline import PublishError from ayon_houdini.api.lib import evalParmNoFrame from ayon_houdini.api import plugin @@ -28,7 +29,13 @@ def process(self, instance): rop = hou.node(instance.data.get("instance_node")) - default_prefix = evalParmNoFrame(rop, "picture") + try: + default_prefix = evalParmNoFrame(rop, "picture") + except Exception as exc: + raise PublishError( + f"Failed evaluating parameter 'picture' on Rop node: {rop.path()}", + detail=f"{exc}" + ) render_products = [] # Default beauty AOV diff --git a/client/ayon_houdini/plugins/publish/collect_mantra_rop.py b/client/ayon_houdini/plugins/publish/collect_mantra_rop.py index 2f4cdff320..d6588025a4 100644 --- a/client/ayon_houdini/plugins/publish/collect_mantra_rop.py +++ b/client/ayon_houdini/plugins/publish/collect_mantra_rop.py @@ -4,6 +4,7 @@ import hou import pyblish.api +from ayon_core.pipeline import PublishError from ayon_houdini.api.lib import evalParmNoFrame from ayon_houdini.api import plugin @@ -28,13 +29,13 @@ def process(self, instance): rop = hou.node(instance.data.get("instance_node")) - default_prefix = evalParmNoFrame(rop, "vm_picture") + default_prefix = self.evalParmNoFrame(rop, "vm_picture") render_products = [] export_prefix = None export_products = [] if instance.data["splitRender"]: - export_prefix = evalParmNoFrame( + export_prefix = self.evalParmNoFrame( rop, "soho_diskfile", pad_character="0" ) beauty_export_product = self.get_render_product_name( @@ -74,7 +75,7 @@ def process(self, instance): aov_enabled = rop.evalParm(aov_boolean) has_aov_path = rop.evalParm(aov_name) if has_aov_path and aov_enabled == 1: - aov_prefix = evalParmNoFrame(rop, aov_name) + aov_prefix = self.evalParmNoFrame(rop, aov_name) aov_product = self.get_render_product_name( prefix=aov_prefix, suffix=None ) @@ -137,3 +138,12 @@ def replace(match): os.path.join(dir, (file % i)).replace("\\", "/")) return expected_files + + def evalParmNoFrame(self, rop, parm, **kwargs): + try: + return evalParmNoFrame(rop, parm, **kwargs) + except Exception as exc: + raise PublishError( + f"Failed evaluating parameter '{parm}' on Rop node: {rop.path()}", + detail=f"{exc}" + ) \ No newline at end of file diff --git a/client/ayon_houdini/plugins/publish/collect_redshift_rop.py b/client/ayon_houdini/plugins/publish/collect_redshift_rop.py index 3f79438ee2..06af1b627a 100644 --- a/client/ayon_houdini/plugins/publish/collect_redshift_rop.py +++ b/client/ayon_houdini/plugins/publish/collect_redshift_rop.py @@ -4,6 +4,7 @@ import hou import pyblish.api +from ayon_core.pipeline import PublishError from ayon_houdini.api.lib import evalParmNoFrame from ayon_houdini.api import plugin @@ -27,12 +28,12 @@ class CollectRedshiftROPRenderProducts(plugin.HoudiniInstancePlugin): def process(self, instance): rop = hou.node(instance.data.get("instance_node")) - default_prefix = evalParmNoFrame(rop, "RS_outputFileNamePrefix") + default_prefix = self.evalParmNoFrame(rop, "RS_outputFileNamePrefix") beauty_suffix = rop.evalParm("RS_outputBeautyAOVSuffix") export_products = [] if instance.data["splitRender"]: - export_prefix = evalParmNoFrame( + export_prefix = self.evalParmNoFrame( rop, "RS_archive_file", pad_character="0" ) beauty_export_product = self.get_render_product_name( @@ -80,7 +81,7 @@ def process(self, instance): continue aov_suffix = rop.evalParm(f"RS_aovSuffix_{i}") - aov_prefix = evalParmNoFrame(rop, f"RS_aovCustomPrefix_{i}") + aov_prefix = self.evalParmNoFrame(rop, f"RS_aovCustomPrefix_{i}") if not aov_prefix: aov_prefix = default_prefix @@ -163,3 +164,12 @@ def replace(match): os.path.join(dir, (file % i)).replace("\\", "/")) return expected_files + + def evalParmNoFrame(self, rop, parm, **kwargs): + try: + return evalParmNoFrame(rop, parm, **kwargs) + except Exception as exc: + raise PublishError( + f"Failed evaluating parameter '{parm}' on Rop node: {rop.path()}", + detail=f"{exc}" + ) \ No newline at end of file diff --git a/client/ayon_houdini/plugins/publish/collect_usd_render.py b/client/ayon_houdini/plugins/publish/collect_usd_render.py index 2934cce246..4abba65579 100644 --- a/client/ayon_houdini/plugins/publish/collect_usd_render.py +++ b/client/ayon_houdini/plugins/publish/collect_usd_render.py @@ -4,6 +4,7 @@ import hou import pyblish.api +from ayon_core.pipeline import PublishError from ayon_houdini.api import plugin from ayon_houdini.api.lib import evalParmNoFrame @@ -31,7 +32,7 @@ def process(self, instance): if instance.data["splitRender"]: # USD file output - lop_output = evalParmNoFrame( + lop_output = self.evalParmNoFrame( rop, "lopoutput", pad_character="#" ) @@ -40,7 +41,7 @@ def process(self, instance): # TODO: It is possible for a user to disable this # TODO: When enabled I think only the basename of the `lopoutput` # parm is preserved, any parent folders defined are likely ignored - folder = evalParmNoFrame( + folder = self.evalParmNoFrame( rop, "savetodirectory_directory", pad_character="#" ) @@ -68,3 +69,12 @@ def replace_to_f(match): # stub required data for Submit Publish Job publish plug-in instance.data["attachTo"] = [] + + def evalParmNoFrame(self, rop, parm, **kwargs): + try: + return evalParmNoFrame(rop, parm, **kwargs) + except Exception as exc: + raise PublishError( + f"Failed evaluating parameter '{parm}' on Rop node: {rop.path()}", + detail=f"{exc}" + ) \ No newline at end of file diff --git a/client/ayon_houdini/plugins/publish/collect_vray_rop.py b/client/ayon_houdini/plugins/publish/collect_vray_rop.py index ef0349f872..c44ed4245e 100644 --- a/client/ayon_houdini/plugins/publish/collect_vray_rop.py +++ b/client/ayon_houdini/plugins/publish/collect_vray_rop.py @@ -4,6 +4,7 @@ import hou import pyblish.api +from ayon_core.pipeline import PublishError from ayon_houdini.api.lib import evalParmNoFrame from ayon_houdini.api import plugin @@ -28,14 +29,14 @@ def process(self, instance): rop = hou.node(instance.data.get("instance_node")) - default_prefix = evalParmNoFrame(rop, "SettingsOutput_img_file_path") + default_prefix = self.evalParmNoFrame(rop, "SettingsOutput_img_file_path") render_products = [] # TODO: add render elements if render element export_prefix = None export_products = [] if instance.data["splitRender"]: - export_prefix = evalParmNoFrame( + export_prefix = self.evalParmNoFrame( rop, "render_export_filepath", pad_character="0" ) beauty_export_product = self.get_render_product_name( @@ -132,3 +133,12 @@ def replace(match): os.path.join(dir, (file % i)).replace("\\", "/")) return expected_files + + def evalParmNoFrame(self, rop, parm, **kwargs): + try: + return evalParmNoFrame(rop, parm, **kwargs) + except Exception as exc: + raise PublishError( + f"Failed evaluating parameter '{parm}' on Rop node: {rop.path()}", + detail=f"{exc}" + ) \ No newline at end of file diff --git a/client/ayon_houdini/plugins/publish/extract_render.py b/client/ayon_houdini/plugins/publish/extract_render.py index 0ed7f9108d..d4a0832e07 100644 --- a/client/ayon_houdini/plugins/publish/extract_render.py +++ b/client/ayon_houdini/plugins/publish/extract_render.py @@ -62,7 +62,14 @@ def process(self, instance): # previously rendered version. This situation breaks the publishing. # because There will be missing frames as ROP nodes typically cannot render different # frame ranges for each AOV; they always use the same frame range for all AOVs. - self.render_rop(instance) + try: + self.render_rop(instance) + except Exception as e: + raise PublishError( + "Render failed or interrupted", + description=f"An Error occurred while rendering {rop_node.path()}", + detail=f"{e}" + ) # `ExpectedFiles` is a list that includes one dict. expected_files = instance.data["expectedFiles"][0] diff --git a/client/ayon_houdini/plugins/publish/extract_rop.py b/client/ayon_houdini/plugins/publish/extract_rop.py index 33b212bd2e..ee05313a60 100644 --- a/client/ayon_houdini/plugins/publish/extract_rop.py +++ b/client/ayon_houdini/plugins/publish/extract_rop.py @@ -35,7 +35,17 @@ def process(self, instance: pyblish.api.Instance): # This key might be absent because render targets are not yet implemented # for all product types that use this plugin. if creator_attribute.get("render_target", "local") == "local": - self.render_rop(instance) + try: + self.render_rop(instance) + except Exception as e: + import hou + rop_node = hou.node(instance.data["instance_node"]) + raise PublishError( + "Render failed or interrupted", + description=f"An Error occurred while rendering {rop_node.path()}", + detail=f"{e}" + ) + self.validate_expected_frames(instance) # In some cases representation name is not the the extension diff --git a/client/ayon_houdini/plugins/publish/extract_usd.py b/client/ayon_houdini/plugins/publish/extract_usd.py index 95f80b2df1..47a8f1dba3 100644 --- a/client/ayon_houdini/plugins/publish/extract_usd.py +++ b/client/ayon_houdini/plugins/publish/extract_usd.py @@ -46,7 +46,14 @@ def process(self, instance): mapping.update(instance_mapping) with remap_paths(ropnode, mapping): - render_rop(ropnode) + try: + render_rop(ropnode) + except Exception as e: + raise PublishError( + "Render failed or interrupted", + description=f"An Error occurred while rendering {ropnode.path()}", + detail=f"{e}" + ) if not os.path.exists(output): PublishError(f"Output does not exist: {output}")