Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use PublishError along publishing #190

Closed
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1ddddab
refactor `RuntimeError` to `PublishError`
MustafaJafar Dec 4, 2024
ee0745b
refactor `assert` to `PublishError`
MustafaJafar Dec 4, 2024
47cd409
remove redundant `message` argument
MustafaJafar Dec 4, 2024
4502143
better error message in `SaveCurrentScene`
MustafaJafar Dec 4, 2024
6c891cf
add error description in `SaveCurrentScene`
MustafaJafar Dec 4, 2024
fea6de3
refactor some errors to `PublishError`
MustafaJafar Dec 4, 2024
84be3d4
Use `PublishError` to the caller functions in publish plugins for `re…
MustafaJafar Dec 5, 2024
ece72b3
Move the `PublishError` to the collector
MustafaJafar Dec 5, 2024
65249cc
revert `copy_instance_data` and move the `PublishError` to the `proce…
MustafaJafar Dec 5, 2024
bde4ab3
replace `●` with regular dash `-`
MustafaJafar Dec 5, 2024
0363a57
move `evalParmNoFrame` to `HoudiniInstancePlugin`
MustafaJafar Dec 5, 2024
bb44614
Use `PublishValidationError` instead and use better log message
MustafaJafar Dec 6, 2024
452f73e
remove redundant validator
MustafaJafar Dec 6, 2024
ce5a314
Move `publishError` to the caller publish plugin
MustafaJafar Dec 6, 2024
6de4af0
Move the `PublishError` to `HoudiniInstancePlugin`
MustafaJafar Dec 6, 2024
33c2bb3
revert changes in `get_top_referenced_parm`
MustafaJafar Dec 6, 2024
15dbe43
Implement `PublishError` when calling colorspace function.
MustafaJafar Dec 6, 2024
a03e49b
refactor `f{exc}` to `str(exc)`
MustafaJafar Dec 9, 2024
8bb8bf7
add missing argument
MustafaJafar Dec 9, 2024
107012c
refactor `HoudiniInstancePlugin.evalParmNoFrame` to `HoudiniInstanceP…
MustafaJafar Dec 9, 2024
d92689e
Fix `eval_parm_no_frame` call
MustafaJafar Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions client/ayon_houdini/api/lib.py
MustafaJafar marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from ayon_core.pipeline.workfile.workfile_template_builder import (
TemplateProfileNotFound
)
from ayon_core.pipeline.publish import PublishError
from ayon_core.tools.utils import PopupUpdateKeys, SimplePopup
from ayon_core.tools.utils.host_tools import get_tool_by_name

Expand Down Expand Up @@ -106,7 +107,7 @@ def get_output_parameter(node):
elif node_type == "vray_renderer":
return node.parm("SettingsOutput_img_file_path")

raise TypeError("Node type '%s' not supported" % node_type)
raise PublishError(f"Node type '{node_type}' is not supported")


def get_lops_rop_context_options(
Expand Down Expand Up @@ -140,7 +141,8 @@ def get_lops_rop_context_options(
end: float = ropnode.evalParm("f2")
inc: float = ropnode.evalParm("f3")
else:
raise ValueError("Unsupported trange value: %s" % trange)
raise PublishError(f"Unsupported trange value: {trange}"
f" for rop node: {ropnode.path()}")
rop_context_options["ropcook"] = 1.0
rop_context_options["ropstart"] = start
rop_context_options["ropend"] = end
Expand All @@ -160,7 +162,8 @@ def get_lops_rop_context_options(
elif option_type == "float":
value: float = ropnode.evalParm(f"optionfloatvalue{i}")
else:
raise ValueError(f"Unsupported option type: {option_type}")
raise PublishError(f"Unsupported option type: {option_type}"
f" on rop node: '{ropnode.path()}'")
rop_context_options[name] = value

return rop_context_options
Expand Down Expand Up @@ -286,9 +289,11 @@ 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.
import traceback
traceback.print_exc()
raise RuntimeError("Render failed: {0}".format(exc))
raise PublishError(
"Render failed or interrupted",
description=f"An Error occurred while rendering {ropnode.path()}",
detail=f"{exc}"
)


def imprint(node, data, update=False):
Expand Down Expand Up @@ -655,7 +660,7 @@ def get_top_referenced_parm(parm):
processed = set() # disallow infinite loop
while True:
if parm.path() in processed:
raise RuntimeError("Parameter references result in cycle.")
raise PublishError("Parameter references result in cycle.")

processed.add(parm.path())

Expand All @@ -671,7 +676,8 @@ def get_top_referenced_parm(parm):
def evalParmNoFrame(node, parm, pad_character="#"):

parameter = node.parm(parm)
assert parameter, "Parameter does not exist: %s.%s" % (node, parm)
if not parameter:
raise PublishError(f"Parameter does not exist: {node}.{parm}")

# If the parameter has a parameter reference, then get that
# parameter instead as otherwise `unexpandedString()` fails.
Expand All @@ -681,8 +687,10 @@ def evalParmNoFrame(node, parm, pad_character="#"):
try:
raw = parameter.unexpandedString()
except hou.Error as exc:
print("Failed: %s" % parameter)
raise RuntimeError(exc)
raise PublishError(
f"Failed: {parameter}",
detail=f"{exc}"
)

def replace(match):
padding = 1
Expand Down Expand Up @@ -726,8 +734,10 @@ def get_color_management_preferences():
config_path = preferences["config"]
config = PyOpenColorIO.Config.CreateFromFile(config_path)
display = config.getDefaultDisplay()
assert display == preferences["display"], \
"Houdini default OCIO display must match config default display"
if display != preferences["display"]:
raise PublishError(
"Houdini default OCIO display must match config default display"
)
view = config.getDefaultView(display)
preferences["display"] = display
preferences["view"] = view
Expand Down
7 changes: 5 additions & 2 deletions client/ayon_houdini/api/usd.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import ayon_api
from pxr import Usd, Sdf, Tf, Vt, UsdRender

from ayon_core.pipeline.publish import PublishError


log = logging.getLogger(__name__)


Expand Down Expand Up @@ -205,8 +208,8 @@ def get_configured_save_layers(usd_rop, strip_above_layer_break=True):
lop_node = get_usd_rop_loppath(usd_rop)
stage = lop_node.stage(apply_viewport_overrides=False)
if not stage:
raise RuntimeError(
"No valid USD stage for ROP node: " "%s" % usd_rop.path()
raise PublishError(
f"No valid USD stage for ROP node: '{usd_rop.path()}' "
MustafaJafar marked this conversation as resolved.
Show resolved Hide resolved
)

root_layer = stage.GetRootLayer()
Expand Down
6 changes: 3 additions & 3 deletions client/ayon_houdini/plugins/publish/collect_output_node.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pyblish.api
from ayon_core.pipeline.publish import KnownPublishError
from ayon_core.pipeline.publish import PublishError
from ayon_houdini.api import plugin


Expand Down Expand Up @@ -67,8 +67,8 @@ def process(self, instance):
out_node = node.parm("startnode").evalAsNode()

else:
raise KnownPublishError(
"ROP node type '{}' is not supported.".format(node_type)
raise PublishError(
moonyuet marked this conversation as resolved.
Show resolved Hide resolved
f"ROP node type '{node_type}' is not supported."
)

if not out_node:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import pyblish.api

from ayon_core.pipeline.publish import PublishError
from ayon_houdini.api import plugin
from ayon_houdini.api.usd import (
get_usd_render_rop_rendersettings
Expand Down Expand Up @@ -107,10 +108,10 @@ def replace(match):
filename = os.path.join(dirname, filename_base)
filename = filename.replace("\\", "/")

assert "#" in filename, (
"Couldn't resolve render product name "
"with frame number: %s" % name
)
if "#" not in filename:
raise PublishError(
f"Couldn't resolve render product name with frame number: {name}"
)

filenames.append(filename)

Expand Down
12 changes: 8 additions & 4 deletions client/ayon_houdini/plugins/publish/collect_usd_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pyblish.api

from ayon_core.pipeline.create import get_product_name
from ayon_core.pipeline.publish import PublishError
from ayon_houdini.api import plugin
import ayon_houdini.api.usd as usdlib

Expand All @@ -27,8 +28,8 @@ def copy_instance_data(instance_src, instance_dest, attr):
in the source instance's data.

Raises:
KeyError: If the key does not exist on the source instance.
AssertionError: If a parent key already exists on the destination
PublishError: If the key does not exist on the source instance.
PublishError: If a parent key already exists on the destination
instance but is not of the correct type (= is not a dict)

"""
Expand All @@ -38,12 +39,15 @@ def copy_instance_data(instance_src, instance_dest, attr):
keys = attr.split(".")
for i, key in enumerate(keys):
if key not in src_data:
break
raise PublishError(
f"key '{key}' does not exist on the source instance."
)
MustafaJafar marked this conversation as resolved.
Show resolved Hide resolved

src_value = src_data[key]
if i != len(key):
dest_data = dest_data.setdefault(key, {})
assert isinstance(dest_data, dict), "Destination must be a dict"
if not isinstance(dest_data, dict):
raise PublishError("Destination must be a dict.")
src_data = src_value
else:
# Last iteration - assign the value
Expand Down
10 changes: 6 additions & 4 deletions client/ayon_houdini/plugins/publish/extract_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import pyblish.api

from ayon_core.pipeline.publish import PublishError
from ayon_houdini.api import plugin


Expand Down Expand Up @@ -81,7 +82,8 @@ def process(self, instance):
if not os.path.exists(frame)
]
if missing_frames:
# TODO: Use user friendly error reporting.
raise RuntimeError("Failed to complete render extraction. "
"Missing output files: {}".format(
missing_frames))
missing_frames = "\n\n ● ".join(missing_frames)
MustafaJafar marked this conversation as resolved.
Show resolved Hide resolved
raise PublishError(
"Failed to complete render extraction.",
detail=f"Missing output files:\n\n ● {missing_frames}"
)
7 changes: 6 additions & 1 deletion client/ayon_houdini/plugins/publish/extract_rop.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import pyblish.api

from ayon_core.pipeline import publish
from ayon_core.pipeline.publish import PublishError
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import splitext

Expand Down Expand Up @@ -73,7 +74,11 @@ def validate_expected_frames(self, instance: pyblish.api.Instance):
if not os.path.isfile(os.path.join(staging_dir, filename))
]
if missing_filenames:
raise RuntimeError(f"Missing frames: {missing_filenames}")
missing_filenames = "\n\n ● ".join(missing_filenames)
raise PublishError(
"Failed to complete render extraction.",
detail=f"Missing frames:\n\n ● {missing_filenames}"
)

def update_representation_data(self,
instance: pyblish.api.Instance,
Expand Down
10 changes: 7 additions & 3 deletions client/ayon_houdini/plugins/publish/extract_usd.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from ayon_core.pipeline.entity_uri import construct_ayon_entity_uri
from ayon_core.pipeline.publish.lib import get_instance_expected_output_path
from ayon_core.pipeline.publish import PublishError
from ayon_houdini.api import plugin
from ayon_houdini.api.lib import render_rop
from ayon_houdini.api.usd import remap_paths
Expand Down Expand Up @@ -47,7 +48,8 @@ def process(self, instance):
with remap_paths(ropnode, mapping):
render_rop(ropnode)

assert os.path.exists(output), "Output does not exist: %s" % output
if not os.path.exists(output):
PublishError(f"Output does not exist: {output}")

if "representations" not in instance.data:
instance.data["representations"] = []
Expand Down Expand Up @@ -135,5 +137,7 @@ def get_source_paths(
# Single file
return [os.path.join(staging, files)]

raise TypeError(f"Unsupported type for representation files: {files} "
"(supports list or str)")
raise PublishError(
f"Unsupported type for representation files: {files}"
" (supports list or str)"
)
9 changes: 5 additions & 4 deletions client/ayon_houdini/plugins/publish/increment_current_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from ayon_core.pipeline import registered_host
from ayon_core.pipeline.publish import (
get_errored_plugins_from_context,
KnownPublishError
PublishError
)

from ayon_houdini.api import plugin
Expand Down Expand Up @@ -37,7 +37,7 @@ def process(self, context):
plugin.__name__ == "HoudiniSubmitPublishDeadline"
for plugin in errored_plugins
):
raise KnownPublishError(
raise PublishError(
"Skipping incrementing current file because "
"submission to deadline failed."
)
Expand All @@ -46,8 +46,9 @@ def process(self, context):
host = registered_host()
current_file = host.current_file()
if context.data["currentFile"] != current_file:
raise KnownPublishError(
"Collected filename mismatches from current scene name."
raise PublishError(
f"Collected filename '{context.data['currentFile']}'"
f" mismatches from current scene name '{current_file}'."
)

new_filepath = version_up(current_file)
Expand Down
21 changes: 18 additions & 3 deletions client/ayon_houdini/plugins/publish/save_scene.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import inspect
import pyblish.api

from ayon_core.pipeline import registered_host
from ayon_core.pipeline.publish import PublishError

from ayon_houdini.api import plugin

Expand All @@ -16,12 +18,25 @@ def process(self, context):
# Filename must not have changed since collecting
host = registered_host()
current_file = host.get_current_workfile()
assert context.data['currentFile'] == current_file, (
"Collected filename from current scene name."
)
if context.data['currentFile'] != current_file:
raise PublishError(
f"Collected filename '{context.data['currentFile']}' differs"
f" from current scene name '{current_file}'.",
description=self.get_error_description()
)

if host.workfile_has_unsaved_changes():
self.log.info("Saving current file: {}".format(current_file))
host.save_workfile(current_file)
else:
self.log.debug("No unsaved changes, skipping file save..")

def get_error_description(self):
return inspect.cleandoc(
"""### Scene File Name Change During Publishing

This error occurs when you validate the scene and then save it as a new file manually, or if you open a new file and continue publishing.

Please reset the publisher and publish without changing the scene file midway.
"""
)
6 changes: 3 additions & 3 deletions client/ayon_houdini/plugins/publish/validate_frame_token.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import hou

import pyblish.api

from ayon_core.pipeline.publish import PublishError
from ayon_houdini.api import lib, plugin


Expand Down Expand Up @@ -31,8 +31,8 @@ def process(self, instance):

invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError(
"Output settings do no match for '%s'" % instance
raise PublishError(
f"Output settings do no match for '{instance}'"
MustafaJafar marked this conversation as resolved.
Show resolved Hide resolved
)

@classmethod
Expand Down
Loading