fix: close Python workflow client review

This commit is contained in:
lda
2026-08-31 23:38:03 +07:00 Verified
parent 4f946a35ef
commit 5e3d0b6524
15 changed files with 200 additions and 224 deletions
+3 -21
View File
@@ -29,12 +29,8 @@ from wf_transport_rpc_http.client.base import RpcProtocolError
from .errors import (
ArtifactNotFound,
ArtifactVersionConflict,
CapabilityNotFound,
DeploymentNotRunnable,
DeploymentRequired,
ProtocolError,
RevisionConflict,
TransportError,
WorkflowClientError,
)
@@ -64,22 +60,8 @@ def _known_protocol_error(
operation: str,
error: RpcProtocolError,
) -> WorkflowClientError | None:
"""Translate only stable codes or exact legacy missing-resource signals."""
"""Translate only operation-specific errors emitted by the current server."""
code, detail = _server_detail(error)
normalized = code.casefold() if code is not None else ""
if normalized in {"capability_not_found", "capabilitynotfound"}:
return CapabilityNotFound(detail)
if normalized in {"artifact_not_found", "artifactnotfound"}:
return ArtifactNotFound(detail)
if normalized in {"artifact_version_conflict", "artifactversionconflict"}:
return ArtifactVersionConflict(detail)
if normalized in {"revision_conflict", "revisionconflict"}:
return RevisionConflict(detail)
if normalized in {"deployment_required", "deploymentrequired"}:
return DeploymentRequired()
if normalized in {"deployment_not_runnable", "deploymentnotrunnable"}:
return DeploymentNotRunnable(error=detail)
# The current RPC server reports expected application exception class names
# in ``data.code``. A generic KeyError is safe to specialize only when both
# the operation and its exact resource phrase agree.
@@ -87,11 +69,11 @@ def _known_protocol_error(
if operation.startswith("workflow.capabilities.") and (
"unknown workflow capability" in detail
):
return CapabilityNotFound(detail)
return CapabilityNotFound(detail, code=error.code, data=error.data)
if operation == "workflow.artifacts.inspect" and (
"unknown workflow artifact" in detail
):
return ArtifactNotFound(detail)
return ArtifactNotFound(detail, code=error.code, data=error.data)
return None
+2 -2
View File
@@ -116,7 +116,7 @@ class Deployment:
deployment_id=self.deployment_id,
artifact=f"{self.artifact_id}.v{self.artifact_version}",
runnable=self.runnable,
diagnostics=f"{len(self.diagnostics)} diagnostics",
diagnostics=f"{len(self._diagnostics)} diagnostics",
)
def _repr_html_(self) -> str:
@@ -126,7 +126,7 @@ class Deployment:
artifact=f"{self.artifact_id}.v{self.artifact_version}",
bindings=f"{len(self.bindings)} bindings",
runnable=self.runnable,
diagnostics=f"{len(self.diagnostics)} diagnostics",
diagnostics=f"{len(self._diagnostics)} diagnostics",
)
@property
+16 -3
View File
@@ -11,6 +11,20 @@ from wf_artifacts import DependencyDiagnostic
class WorkflowClientError(Exception):
"""Base class for errors that can be handled by workflow callers."""
code: int | str | None
data: object
def __init__(
self,
message: str = "",
*,
code: int | str | None = None,
data: object = None,
) -> None:
self.code = code
self.data = deepcopy(data)
super().__init__(message)
class TransportError(WorkflowClientError):
"""The client could not communicate with the workflow service."""
@@ -29,10 +43,9 @@ class ProtocolError(WorkflowClientError):
message: str,
data: object = None,
) -> None:
self.code = code
self.message = message
self.data = deepcopy(data)
super().__init__(str(self))
super().__init__(message, code=code, data=data)
self.args = (str(self),)
def __str__(self) -> str:
if isinstance(self.data, dict) and isinstance(self.data.get("message"), str):