👽 change error handling

This commit is contained in:
Ondrej Samohel 2022-09-09 10:38:05 +02:00
parent d59e188ab0
commit 42c6c846e4
No known key found for this signature in database
GPG key ID: 02376E18990A97C6
6 changed files with 109 additions and 52 deletions

View file

@ -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()]

View file

@ -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:

View file

@ -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)

View file

@ -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()]

View file

@ -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]

View file

@ -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