Let me explore the repository structure and find all relevant exception definitions and usages.
Now let me look at the ConditionError usage more closely and the MissingTemplateVariables and MissingResourceError exceptions:
Now let me look at how the deploy method uses ValidationError:
Now let me see where validate is called during create:
Now let me look at the Pod.execute method more closely:
Now let me look at how client_with_basic_auth works:
Now let me see the NNCP methods in full context:
Let me also look at MissingTemplateVariables usage more closely:
Now let me check the __init__ of Resource to see how schema_validation_enabled is handled:
Now let me also check the wait_for_condition method signature more closely:
Let me also look at MissingResourceResError usage:
Now let me check the test for ResourceTeardownError:
Let me see how SecretTestExit is defined:
Let me check the import path for all exceptions:
Now I have a thorough understanding of the codebase. Let me write the reference documentation.
Error Handling and Exception Reference
All custom exceptions are defined in ocp_resources.exceptions and can be imported directly:
from ocp_resources.exceptions import (
ExecOnPodError,
MissingRequiredArgumentError,
ResourceTeardownError,
ValidationError,
ConditionError,
NNCPConfigurationFailed,
ClientWithBasicAuthError,
MissingResourceError,
MissingTemplateVariables,
)
Tip: All exceptions inherit from Python's built-in
Exceptionclass and can be caught with a bareexcept Exceptionif needed.
ExecOnPodError
Raised when a command executed inside a pod via Pod.execute() fails. See Executing Commands in Pods and Retrieving Logs for full usage details.
Import:
from ocp_resources.exceptions import ExecOnPodError
Constructor Parameters:
| Parameter | Type | Description |
|---|---|---|
command |
list[str] |
The command that was executed |
rc |
int |
Return code (-1 if the return code could not be determined) |
out |
str |
Standard output captured from the command |
err |
Any |
Standard error output or error channel details |
Attributes on the caught exception:
| Attribute | Type | Description |
|---|---|---|
cmd |
list[str] |
The command that was executed |
rc |
int |
The return code |
out |
str |
Standard output |
err |
Any |
Standard error or error channel dict |
Raised by: Pod.execute() in the following scenarios:
- Command times out (stream response closes before completion) —
rc=-1 - Error channel returns no status —
rc=-1 - Error channel status is
"Failure"—rc=-1,errcontains the full error channel dict - Command exits with a non-zero exit code —
rccontains the actual exit code
String representation:
Command execution failure: ['ls', '/nonexistent'], RC: 2, OUT: , ERR: ls: cannot access '/nonexistent'
Example:
from ocp_resources.pod import Pod
from ocp_resources.exceptions import ExecOnPodError
pod = Pod(client=client, name="my-pod", namespace="default")
try:
output = pod.execute(command=["ls", "/nonexistent"], timeout=30)
except ExecOnPodError as e:
print(f"Command: {e.cmd}")
print(f"Return code: {e.rc}")
print(f"Stdout: {e.out}")
print(f"Stderr: {e.err}")
Handling non-zero exit codes without exceptions:
# Use ignore_rc=True to suppress ExecOnPodError on non-zero exit codes
output = pod.execute(command=["grep", "pattern", "/var/log/messages"], ignore_rc=True)
MissingRequiredArgumentError
Raised when a resource is instantiated without providing required arguments and no yaml_file or kind_dict was supplied. This error is raised during to_dict(), which is called automatically by create() and deploy().
Import:
from ocp_resources.exceptions import MissingRequiredArgumentError
Constructor Parameters:
| Parameter | Type | Description |
|---|---|---|
argument |
str |
Name of the missing required argument(s) |
Attributes on the caught exception:
| Attribute | Type | Description |
|---|---|---|
argument |
str |
The missing argument name |
String representation:
Missing required argument/s. Either provide yaml_file, kind_dict or pass self.containers
Raised by: The to_dict() method of resource subclasses when required spec fields are not provided. Examples of resources that raise this exception:
| Resource Class | Required Arguments |
|---|---|
Pod |
containers |
StorageClass |
provisioner |
ClusterRoleBinding |
cluster_role |
ClusterResourceQuota |
quota, selector |
CronJob |
job_template, schedule |
InferenceService |
predictor |
IPAddressPool |
addresses |
ResourceQuota |
hard |
UserDefinedNetwork |
topology |
Note: This exception is not raised if you construct the resource using
yaml_fileorkind_dict, since those bypass theto_dict()logic.
Example:
from ocp_resources.pod import Pod
from ocp_resources.exceptions import MissingRequiredArgumentError
try:
pod = Pod(client=client, name="my-pod", namespace="default")
pod.deploy()
except MissingRequiredArgumentError as e:
print(f"Missing: {e.argument}")
# Output: Missing required argument/s. Either provide yaml_file, kind_dict or pass self.containers
ResourceTeardownError
Raised when a resource's clean_up() method returns False during context manager exit. This indicates the resource could not be deleted.
Import:
from ocp_resources.exceptions import ResourceTeardownError
Constructor Parameters:
| Parameter | Type | Description |
|---|---|---|
resource |
Any |
The resource object that failed to tear down |
Attributes on the caught exception:
| Attribute | Type | Description |
|---|---|---|
resource |
Any |
The resource object that failed teardown |
String representation:
Failed to execute teardown for resource <resource>
Raised by: Resource.__exit__() — the context manager exit handler. Specifically, this is raised when:
- The resource was created with
teardown=True(the default). - The
clean_up()method returnsFalse.
Example:
from ocp_resources.pod import Pod
from ocp_resources.exceptions import ResourceTeardownError
try:
with Pod(
client=client,
name="my-pod",
namespace="default",
containers=[{"name": "nginx", "image": "nginx:latest"}],
) as pod:
# Use pod...
pass
# clean_up() is called automatically here
except ResourceTeardownError as e:
print(f"Could not delete: {e.resource}")
Tip: Set
teardown=Falseon the resource constructor if you do not want automatic cleanup on context manager exit, and thus never want this exception raised.
ValidationError
Raised when a resource fails schema validation against the OpenAPI specification. See Validating Resources Against OpenAPI Schemas for full validation guide.
Import:
from ocp_resources.exceptions import ValidationError
Constructor Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
message |
str |
(required) | Human-readable error description |
path |
str |
"" |
JSONPath to the invalid field (e.g., "spec.containers[0].image") |
schema_error |
Any |
None |
Original jsonschema validation error for debugging |
Attributes on the caught exception:
| Attribute | Type | Description |
|---|---|---|
message |
str |
Human-readable error message |
path |
str |
JSONPath to the invalid field |
schema_error |
Any |
Original jsonschema.ValidationError if available |
String representation:
Validation error at 'spec.containers[0].image': Invalid type
When path is empty:
Validation error: Field is required
Raised by:
| Method | Trigger |
|---|---|
resource.validate() |
Called explicitly by user |
resource.create() |
When schema_validation_enabled=True |
resource.update_replace() |
When schema_validation_enabled=True |
Resource.validate_dict() |
Class method for validating raw dicts |
Note:
resource.update()does not trigger validation even whenschema_validation_enabled=True, because updates send partial patches that would fail full schema validation.
Example — explicit validation:
from ocp_resources.pod import Pod
from ocp_resources.exceptions import ValidationError
pod = Pod(client=client, name="my-pod", namespace="default",
containers=[{"name": "nginx", "image": "nginx:latest"}])
try:
pod.validate()
except ValidationError as e:
print(f"Error: {e.message}")
print(f"Path: {e.path}")
if e.schema_error:
print(f"Original error: {e.schema_error}")
Example — auto-validation on create:
from ocp_resources.pod import Pod
from ocp_resources.exceptions import ValidationError
try:
pod = Pod(
client=client,
name="my-pod",
namespace="default",
containers=[{"name": "nginx", "image": "nginx:latest"}],
schema_validation_enabled=True,
)
pod.deploy()
except ValidationError as e:
print(f"Invalid resource: {e}")
Example — validate a raw dictionary:
from ocp_resources.deployment import Deployment
from ocp_resources.exceptions import ValidationError
deployment_dict = {
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {"name": "my-deploy"},
"spec": {"replicas": "three"}, # Wrong type — should be int
}
try:
Deployment.validate_dict(resource_dict=deployment_dict)
except ValidationError as e:
print(f"Validation failed: {e}")
ConditionError
Raised when a resource reaches an undesired stop condition during wait_for_condition(). See Waiting for Resource Conditions and Status for details.
Import:
from ocp_resources.exceptions import ConditionError
Constructor Parameters: Standard Exception — accepts a single string message.
Raised by: Resource.wait_for_condition() when the stop_condition parameter matches before the desired condition is met.
wait_for_condition() parameters relevant to ConditionError:
| Parameter | Type | Default | Description |
|---|---|---|---|
condition |
str |
(required) | Condition type to wait for |
status |
str |
(required) | Expected status value |
timeout |
int |
300 |
Maximum wait time in seconds |
sleep_time |
int |
1 |
Polling interval in seconds |
stop_condition |
str \| None |
None |
Condition type that should abort the wait |
stop_status |
str |
"True" |
Status value for the stop condition |
String representation:
Deployment my-deploy reached stop_condition 'Failed' in status 'True':
{'type': 'Failed', 'status': 'True', 'reason': 'DeadlineExceeded', 'message': '...'}
Note: When
stop_conditionisNone(the default),ConditionErroris never raised. Instead,TimeoutExpiredErroris raised if the desired condition is not met within the timeout.
Example:
from ocp_resources.deployment import Deployment
from ocp_resources.exceptions import ConditionError
from timeout_sampler import TimeoutExpiredError
deploy = Deployment(client=client, name="my-deploy", namespace="default")
try:
deploy.wait_for_condition(
condition="Available",
status="True",
timeout=120,
stop_condition="Failed",
stop_status="True",
)
except ConditionError as e:
print(f"Resource entered failure state: {e}")
except TimeoutExpiredError:
print("Timed out waiting for condition")
NNCPConfigurationFailed
Raised when a NodeNetworkConfigurationPolicy (NNCP) fails to configure on one or more nodes.
Import:
from ocp_resources.exceptions import NNCPConfigurationFailed
Constructor Parameters: Standard Exception — accepts a single string message describing the failure reason and error details.
Raised by: NodeNetworkConfigurationPolicy.wait_for_status_success() in two scenarios:
| Scenario | Message Pattern |
|---|---|
| No matching node found | "{name}. Reason: NoMatchingNode" |
| Configuration failed on nodes | "Reason: FailedToConfigure\n{error_details}" |
Note: When
wait_for_status_success()catchesTimeoutExpiredErrororNNCPConfigurationFailed, it logs the error with node details and re-raises the exception.
Example:
from ocp_resources.node_network_configuration_policy import NodeNetworkConfigurationPolicy
from ocp_resources.exceptions import NNCPConfigurationFailed
from timeout_sampler import TimeoutExpiredError
nncp = NodeNetworkConfigurationPolicy(
client=client,
name="my-nncp",
desired_state={"interfaces": [{"name": "eth1", "type": "ethernet", "state": "up"}]},
)
try:
nncp.deploy()
nncp.wait_for_status_success()
except NNCPConfigurationFailed as e:
print(f"NNCP configuration failed: {e}")
except TimeoutExpiredError:
print("NNCP configuration timed out")
ClientWithBasicAuthError
Raised during OAuth-based client authentication when using username/password credentials to connect to an OpenShift cluster. See Connecting to Clusters for connection methods.
Import:
from ocp_resources.exceptions import ClientWithBasicAuthError
Constructor Parameters: Standard Exception — accepts a single string message.
Raised by: client_configuration_with_basic_auth() in the following scenarios:
| Scenario | Message |
|---|---|
| OAuth well-known endpoint not reachable | "No well-known file found at endpoint" |
| Authorization code not returned after login | "No authorization code found" |
No authorization_endpoint in OAuth config |
"No authorization_endpoint found in well-known file" |
| Token exchange fails | "Failed to authenticate with basic auth" |
Example:
from ocp_resources.exceptions import ClientWithBasicAuthError
from ocp_resources.resource import client_configuration_with_basic_auth
import kubernetes
configuration = kubernetes.client.Configuration()
configuration.verify_ssl = False
try:
api_client = client_configuration_with_basic_auth(
username="admin",
password="password",
host="https://api.cluster.example.com:6443",
configuration=configuration,
)
except ClientWithBasicAuthError as e:
print(f"Authentication failed: {e}")
MissingResourceError
Raised when a resource object fails to generate its internal representation.
Import:
from ocp_resources.exceptions import MissingResourceError
Constructor Parameters:
| Parameter | Type | Description |
|---|---|---|
name |
str |
Name of the resource that could not be generated |
Attributes on the caught exception:
| Attribute | Type | Description |
|---|---|---|
resource_name |
str |
The resource name |
String representation:
Failed to generate resource: my-resource
Example:
from ocp_resources.exceptions import MissingResourceError
try:
# Operations that may fail to generate a resource
...
except MissingResourceError as e:
print(f"Resource generation failed: {e.resource_name}")
MissingTemplateVariables
Raised when rendering a YAML template and not all required template variables have been provided.
Import:
from ocp_resources.exceptions import MissingTemplateVariables
Constructor Parameters:
| Parameter | Type | Description |
|---|---|---|
var |
str |
Name of the missing template variable |
template |
str |
Path to the template file |
Attributes on the caught exception:
| Attribute | Type | Description |
|---|---|---|
var |
str |
The missing variable name |
template |
str |
The template file path |
String representation:
Missing variables image for template tests/manifests/vm.yaml
Example:
from ocp_resources.exceptions import MissingTemplateVariables
try:
result = generate_yaml_from_template(name="my-vm")
# If template also requires 'image', raises MissingTemplateVariables
except MissingTemplateVariables as e:
print(f"Variable '{e.var}' missing in template '{e.template}'")
Common Error-Handling Patterns
Catching Multiple Library Exceptions
from ocp_resources.exceptions import (
ExecOnPodError,
MissingRequiredArgumentError,
ResourceTeardownError,
ValidationError,
)
try:
with Pod(client=client, name="worker", namespace="default",
containers=[{"name": "app", "image": "myapp:latest"}],
schema_validation_enabled=True) as pod:
pod.execute(command=["python", "run_task.py"])
except ValidationError as e:
print(f"Invalid resource spec: {e}")
except ExecOnPodError as e:
print(f"Task failed (rc={e.rc}): {e.err}")
except ResourceTeardownError as e:
print(f"Pod cleanup failed: {e}")
except MissingRequiredArgumentError as e:
print(f"Missing field: {e.argument}")
Safe Condition Waiting with Early Abort
from ocp_resources.exceptions import ConditionError
from timeout_sampler import TimeoutExpiredError
try:
resource.wait_for_condition(
condition="Ready",
status="True",
timeout=180,
stop_condition="Failed",
stop_status="True",
)
except ConditionError:
# Resource entered a terminal failure state — no point waiting further
resource.clean_up()
raise
except TimeoutExpiredError:
# Condition not met within timeout — may be transient
print("Resource is taking too long, investigating...")
Ignoring Non-Critical Command Failures
from ocp_resources.exceptions import ExecOnPodError
# Method 1: Use ignore_rc=True
output = pod.execute(command=["grep", "ERROR", "/var/log/app.log"], ignore_rc=True)
# Method 2: Catch and inspect the return code
try:
output = pod.execute(command=["test", "-f", "/tmp/lockfile"])
except ExecOnPodError as e:
if e.rc == 1:
print("Lock file does not exist — proceeding")
else:
raise # Re-raise unexpected errors
Validation Before Batch Deployment
from ocp_resources.exceptions import ValidationError
resources = [pod1, pod2, deployment1, service1]
# Pre-validate all resources before deploying any
errors = []
for resource in resources:
try:
resource.validate()
except ValidationError as e:
errors.append((resource.name, str(e)))
if errors:
for name, err in errors:
print(f" {name}: {err}")
raise SystemExit("Fix validation errors before deploying")
for resource in resources:
resource.deploy()
Exception Hierarchy Summary
| Exception | Parent | Module |
|---|---|---|
ExecOnPodError |
Exception |
ocp_resources.exceptions |
MissingRequiredArgumentError |
Exception |
ocp_resources.exceptions |
ResourceTeardownError |
Exception |
ocp_resources.exceptions |
ValidationError |
Exception |
ocp_resources.exceptions |
ConditionError |
Exception |
ocp_resources.exceptions |
NNCPConfigurationFailed |
Exception |
ocp_resources.exceptions |
ClientWithBasicAuthError |
Exception |
ocp_resources.exceptions |
MissingResourceError |
Exception |
ocp_resources.exceptions |
MissingTemplateVariables |
Exception |
ocp_resources.exceptions |
Warning:
MissingResourceResErroris deprecated and will be removed in a future release. UseMissingResourceErrorinstead.