mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-02 08:54:53 +01:00
👽 change error handling
This commit is contained in:
parent
d59e188ab0
commit
42c6c846e4
6 changed files with 109 additions and 52 deletions
|
|
@ -1,8 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pyblish.api
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from openpype.pipeline.publish import ValidateContentsOrder
|
||||
from openpype.pipeline import PublishValidationError
|
||||
|
||||
|
||||
class ValidateAbcPrimitiveToDetail(pyblish.api.InstancePlugin):
|
||||
|
|
@ -16,7 +16,7 @@ class ValidateAbcPrimitiveToDetail(pyblish.api.InstancePlugin):
|
|||
|
||||
"""
|
||||
|
||||
order = ValidateContentsOrder + 0.1
|
||||
order = pyblish.api.ValidatorOrder + 0.1
|
||||
families = ["pointcache"]
|
||||
hosts = ["houdini"]
|
||||
label = "Validate Primitive to Detail (Abc)"
|
||||
|
|
@ -24,15 +24,24 @@ class ValidateAbcPrimitiveToDetail(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError(
|
||||
"Primitives found with inconsistent primitive "
|
||||
"to detail attributes. See log."
|
||||
raise PublishValidationError(
|
||||
("Primitives found with inconsistent primitive "
|
||||
"to detail attributes. See log."),
|
||||
title=self.label
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
output = instance.data["output_node"]
|
||||
output_node = instance.data.get("output_node")
|
||||
if output_node is None:
|
||||
node = instance.data["members"][0]
|
||||
cls.log.error(
|
||||
"SOP Output node in '%s' does not exist. "
|
||||
"Ensure a valid SOP output path is set." % node.path()
|
||||
)
|
||||
|
||||
return [node.path()]
|
||||
|
||||
rop = instance.data["members"][0]
|
||||
pattern = rop.parm("prim_to_detail_pattern").eval().strip()
|
||||
|
|
@ -67,7 +76,7 @@ class ValidateAbcPrimitiveToDetail(pyblish.api.InstancePlugin):
|
|||
|
||||
# Check if the primitive attribute exists
|
||||
frame = instance.data.get("frameStart", 0)
|
||||
geo = output.geometryAtFrame(frame)
|
||||
geo = output_node.geometryAtFrame(frame)
|
||||
|
||||
# If there are no primitives on the start frame then it might be
|
||||
# something that is emitted over time. As such we can't actually
|
||||
|
|
@ -86,7 +95,7 @@ class ValidateAbcPrimitiveToDetail(pyblish.api.InstancePlugin):
|
|||
"Geometry Primitives are missing "
|
||||
"path attribute: `%s`" % path_attr
|
||||
)
|
||||
return [output.path()]
|
||||
return [output_node.path()]
|
||||
|
||||
# Ensure at least a single string value is present
|
||||
if not attrib.strings():
|
||||
|
|
@ -94,7 +103,7 @@ class ValidateAbcPrimitiveToDetail(pyblish.api.InstancePlugin):
|
|||
"Primitive path attribute has no "
|
||||
"string values: %s" % path_attr
|
||||
)
|
||||
return [output.path()]
|
||||
return [output_node.path()]
|
||||
|
||||
paths = None
|
||||
for attr in pattern.split(" "):
|
||||
|
|
@ -130,4 +139,4 @@ class ValidateAbcPrimitiveToDetail(pyblish.api.InstancePlugin):
|
|||
"Path has multiple values: %s (path: %s)"
|
||||
% (list(values), path)
|
||||
)
|
||||
return [output.path()]
|
||||
return [output_node.path()]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import pyblish.api
|
||||
|
||||
from openpype.pipeline.publish import ValidateContentsOrder
|
||||
from openpype.pipeline import PublishValidationError
|
||||
|
||||
|
||||
class ValidateAlembicInputNode(pyblish.api.InstancePlugin):
|
||||
|
|
@ -12,7 +11,7 @@ class ValidateAlembicInputNode(pyblish.api.InstancePlugin):
|
|||
|
||||
"""
|
||||
|
||||
order = ValidateContentsOrder + 0.1
|
||||
order = pyblish.api.ValidatorOrder + 0.1
|
||||
families = ["pointcache"]
|
||||
hosts = ["houdini"]
|
||||
label = "Validate Input Node (Abc)"
|
||||
|
|
@ -20,18 +19,28 @@ class ValidateAlembicInputNode(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError(
|
||||
"Primitive types found that are not supported"
|
||||
"for Alembic output."
|
||||
raise PublishValidationError(
|
||||
("Primitive types found that are not supported"
|
||||
"for Alembic output."),
|
||||
title=self.label
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
invalid_prim_types = ["VDB", "Volume"]
|
||||
node = instance.data["output_node"]
|
||||
output_node = instance.data.get("output_node")
|
||||
|
||||
if not hasattr(node, "geometry"):
|
||||
if output_node is None:
|
||||
node = instance.data["members"][0]
|
||||
cls.log.error(
|
||||
"SOP Output node in '%s' does not exist. "
|
||||
"Ensure a valid SOP output path is set." % node.path()
|
||||
)
|
||||
|
||||
return [node.path()]
|
||||
|
||||
if not hasattr(output_node, "geometry"):
|
||||
# In the case someone has explicitly set an Object
|
||||
# node instead of a SOP node in Geometry context
|
||||
# then for now we ignore - this allows us to also
|
||||
|
|
@ -40,7 +49,7 @@ class ValidateAlembicInputNode(pyblish.api.InstancePlugin):
|
|||
return
|
||||
|
||||
frame = instance.data.get("frameStart", 0)
|
||||
geo = node.geometryAtFrame(frame)
|
||||
geo = output_node.geometryAtFrame(frame)
|
||||
|
||||
invalid = False
|
||||
for prim_type in invalid_prim_types:
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Validator plugin for Houdini Camera ROP settings."""
|
||||
import pyblish.api
|
||||
from openpype.pipeline.publish import ValidateContentsOrder
|
||||
from openpype.pipeline import PublishValidationError
|
||||
|
||||
|
||||
class ValidateCameraROP(pyblish.api.InstancePlugin):
|
||||
"""Validate Camera ROP settings."""
|
||||
|
||||
order = ValidateContentsOrder
|
||||
order = pyblish.api.ValidatorOrder
|
||||
families = ["camera"]
|
||||
hosts = ["houdini"]
|
||||
label = "Camera ROP"
|
||||
|
|
@ -14,30 +16,45 @@ class ValidateCameraROP(pyblish.api.InstancePlugin):
|
|||
|
||||
import hou
|
||||
|
||||
node = instance.data["members"][0]
|
||||
node = hou.node(instance.data.get("instance_node"))
|
||||
if node.parm("use_sop_path").eval():
|
||||
raise RuntimeError(
|
||||
"Alembic ROP for Camera export should not be "
|
||||
"set to 'Use Sop Path'. Please disable."
|
||||
raise PublishValidationError(
|
||||
("Alembic ROP for Camera export should not be "
|
||||
"set to 'Use Sop Path'. Please disable."),
|
||||
title=self.label
|
||||
)
|
||||
|
||||
# Get the root and objects parameter of the Alembic ROP node
|
||||
root = node.parm("root").eval()
|
||||
objects = node.parm("objects").eval()
|
||||
assert root, "Root parameter must be set on Alembic ROP"
|
||||
assert root.startswith("/"), "Root parameter must start with slash /"
|
||||
assert objects, "Objects parameter must be set on Alembic ROP"
|
||||
assert len(objects.split(" ")) == 1, "Must have only a single object."
|
||||
errors = []
|
||||
if not root:
|
||||
errors.append("Root parameter must be set on Alembic ROP")
|
||||
if not root.startswith("/"):
|
||||
errors.append("Root parameter must start with slash /")
|
||||
if not objects:
|
||||
errors.append("Objects parameter must be set on Alembic ROP")
|
||||
if len(objects.split(" ")) != 1:
|
||||
errors.append("Must have only a single object.")
|
||||
|
||||
if errors:
|
||||
for error in errors:
|
||||
self.log.error(error)
|
||||
raise PublishValidationError(
|
||||
"Some checks failed, see validator log.",
|
||||
title=self.label)
|
||||
|
||||
# Check if the object exists and is a camera
|
||||
path = root + "/" + objects
|
||||
camera = hou.node(path)
|
||||
|
||||
if not camera:
|
||||
raise ValueError("Camera path does not exist: %s" % path)
|
||||
raise PublishValidationError(
|
||||
"Camera path does not exist: %s" % path,
|
||||
title=self.label)
|
||||
|
||||
if camera.type().name() != "cam":
|
||||
raise ValueError(
|
||||
"Object set in Alembic ROP is not a camera: "
|
||||
"%s (type: %s)" % (camera, camera.type().name())
|
||||
)
|
||||
raise PublishValidationError(
|
||||
("Object set in Alembic ROP is not a camera: "
|
||||
"{} (type: {})").format(camera, camera.type().name()),
|
||||
title=self.label)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pyblish.api
|
||||
from openpype.pipeline.publish import ValidateContentsOrder
|
||||
from openpype.pipeline import PublishValidationError
|
||||
|
||||
|
||||
class ValidatePrimitiveHierarchyPaths(pyblish.api.InstancePlugin):
|
||||
|
|
@ -19,16 +21,24 @@ class ValidatePrimitiveHierarchyPaths(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError(
|
||||
"See log for details. " "Invalid nodes: {0}".format(invalid)
|
||||
raise PublishValidationError(
|
||||
"See log for details. " "Invalid nodes: {0}".format(invalid),
|
||||
title=self.label
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
import hou
|
||||
output_node = instance.data.get("output_node")
|
||||
|
||||
output = instance.data["output_node"]
|
||||
if output_node is None:
|
||||
node = instance.data["members"][0]
|
||||
cls.log.error(
|
||||
"SOP Output node in '%s' does not exist. "
|
||||
"Ensure a valid SOP output path is set." % node.path()
|
||||
)
|
||||
|
||||
return [node.path()]
|
||||
|
||||
rop = instance.data["members"][0]
|
||||
build_from_path = rop.parm("build_from_path").eval()
|
||||
|
|
@ -52,7 +62,7 @@ class ValidatePrimitiveHierarchyPaths(pyblish.api.InstancePlugin):
|
|||
|
||||
# Check if the primitive attribute exists
|
||||
frame = instance.data.get("frameStart", 0)
|
||||
geo = output.geometryAtFrame(frame)
|
||||
geo = output_node.geometryAtFrame(frame)
|
||||
|
||||
# If there are no primitives on the current frame then we can't
|
||||
# check whether the path names are correct. So we'll just issue a
|
||||
|
|
@ -73,7 +83,7 @@ class ValidatePrimitiveHierarchyPaths(pyblish.api.InstancePlugin):
|
|||
"Geometry Primitives are missing "
|
||||
"path attribute: `%s`" % path_attr
|
||||
)
|
||||
return [output.path()]
|
||||
return [output_node.path()]
|
||||
|
||||
# Ensure at least a single string value is present
|
||||
if not attrib.strings():
|
||||
|
|
@ -81,7 +91,7 @@ class ValidatePrimitiveHierarchyPaths(pyblish.api.InstancePlugin):
|
|||
"Primitive path attribute has no "
|
||||
"string values: %s" % path_attr
|
||||
)
|
||||
return [output.path()]
|
||||
return [output_node.path()]
|
||||
|
||||
paths = geo.primStringAttribValues(path_attr)
|
||||
# Ensure all primitives are set to a valid path
|
||||
|
|
@ -93,4 +103,4 @@ class ValidatePrimitiveHierarchyPaths(pyblish.api.InstancePlugin):
|
|||
"Prims have no value for attribute `%s` "
|
||||
"(%s of %s prims)" % (path_attr, len(invalid_prims), num_prims)
|
||||
)
|
||||
return [output.path()]
|
||||
return [output_node.path()]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import pyblish.api
|
||||
from openpype.pipeline import PublishXmlValidationError
|
||||
from openpype.pipeline import PublishValidationError
|
||||
|
||||
|
||||
class ValidateSopOutputNode(pyblish.api.InstancePlugin):
|
||||
|
|
@ -24,10 +24,9 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin):
|
|||
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise PublishXmlValidationError(
|
||||
self,
|
||||
message="Output node(s) `%s` are incorrect. " % invalid,
|
||||
title=self.label
|
||||
raise PublishValidationError(
|
||||
"Output node(s) are incorrect",
|
||||
title="Invalid output node(s)"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
|
@ -35,7 +34,7 @@ class ValidateSopOutputNode(pyblish.api.InstancePlugin):
|
|||
|
||||
import hou
|
||||
|
||||
output_node = instance.data["output_node"]
|
||||
output_node = instance.data.get("output_node")
|
||||
|
||||
if output_node is None:
|
||||
node = instance.data["members"][0]
|
||||
|
|
|
|||
|
|
@ -2,22 +2,30 @@
|
|||
import openpype.api
|
||||
import pyblish.api
|
||||
import hou
|
||||
from openpype.pipeline import (
|
||||
PublishValidationError,
|
||||
OptionalPyblishPluginMixin
|
||||
)
|
||||
from openpype.pipeline.publish import RepairAction
|
||||
|
||||
|
||||
class ValidateWorkfilePaths(pyblish.api.InstancePlugin):
|
||||
class ValidateWorkfilePaths(
|
||||
pyblish.api.InstancePlugin, OptionalPyblishPluginMixin):
|
||||
"""Validate workfile paths so they are absolute."""
|
||||
|
||||
order = pyblish.api.ValidatorOrder
|
||||
families = ["workfile"]
|
||||
hosts = ["houdini"]
|
||||
label = "Validate Workfile Paths"
|
||||
actions = [openpype.api.RepairAction]
|
||||
actions = [RepairAction]
|
||||
optional = True
|
||||
|
||||
node_types = ["file", "alembic"]
|
||||
prohibited_vars = ["$HIP", "$JOB"]
|
||||
|
||||
def process(self, instance):
|
||||
if not self.is_active(instance.data):
|
||||
return
|
||||
invalid = self.get_invalid()
|
||||
self.log.info(
|
||||
"node types to check: {}".format(", ".join(self.node_types)))
|
||||
|
|
@ -29,13 +37,18 @@ class ValidateWorkfilePaths(pyblish.api.InstancePlugin):
|
|||
self.log.error(
|
||||
"{}: {}".format(param.path(), param.unexpandedString()))
|
||||
|
||||
raise RuntimeError("Invalid paths found")
|
||||
raise PublishValidationError(
|
||||
"Invalid paths found", title=self.label)
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls):
|
||||
invalid = []
|
||||
for param, _ in hou.fileReferences():
|
||||
# it might return None for some reason
|
||||
if not param:
|
||||
continue
|
||||
# skip nodes we are not interested in
|
||||
cls.log.debug(param)
|
||||
if param.node().type().name() not in cls.node_types:
|
||||
continue
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue