Skip to content

Commit 93dd525

Browse files
committed
fix: Improve PodmanConnectionError for all methods
1 parent 5a80693 commit 93dd525

File tree

2 files changed

+60
-108
lines changed

2 files changed

+60
-108
lines changed

podman/client.py

+60-58
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from pathlib import Path
77
from typing import Any, Optional
88

9-
from podman.errors import PodmanConnectionError
9+
from podman.errors.exceptions import APIError, PodmanConnectionError
1010
from podman.api import cached_property
1111
from podman.api.client import APIClient
1212
from podman.api.path_utils import get_runtime_dir
@@ -61,37 +61,42 @@ def __init__(self, **kwargs) -> None:
6161
super().__init__()
6262
config = PodmanConfig()
6363

64-
self.api_kwargs = kwargs.copy()
64+
api_kwargs = kwargs.copy()
6565

66-
if "connection" in self.api_kwargs:
67-
connection = config.services[self.api_kwargs.get("connection")]
68-
self.api_kwargs["base_url"] = connection.url.geturl()
66+
if "connection" in api_kwargs:
67+
connection = config.services[api_kwargs.get("connection")]
68+
api_kwargs["base_url"] = connection.url.geturl()
6969

7070
# Override configured identity, if provided in arguments
71-
self.api_kwargs["identity"] = kwargs.get("identity", str(connection.identity))
72-
elif "base_url" not in self.api_kwargs:
71+
api_kwargs["identity"] = kwargs.get("identity", str(connection.identity))
72+
elif "base_url" not in api_kwargs:
7373
path = str(Path(get_runtime_dir()) / "podman" / "podman.sock")
74-
self.api_kwargs["base_url"] = "http+unix://" + path
74+
api_kwargs["base_url"] = "http+unix://" + path
75+
self.api = APIClient(**api_kwargs)
7576

76-
try:
77-
self.api = APIClient(**self.api_kwargs)
78-
response = self.api.get("_ping")
77+
self._verify_connection()
7978

80-
if response.status_code != 200:
79+
def _verify_connection(self):
80+
"""Verify connection to Podman daemon during initialization.
81+
82+
Raises:
83+
PodmanException: If unable to connect to Podman daemon
84+
"""
85+
try:
86+
# Attempt to get version info to verify connection
87+
self.version()
88+
except APIError as e:
89+
if "No such file or directory" in str(e):
8190
raise PodmanConnectionError(
82-
message=f"Unexpected response from Podman service: {response.status_code}",
83-
environment=os.environ,
84-
host=self.api_kwargs.get("base_url"),
85-
original_error=None,
86-
)
87-
except PodmanConnectionError:
88-
raise
91+
"Error while connecting to Podman daemon: "
92+
f"Could not find socket file - {str(e)}"
93+
) from e
94+
raise PodmanConnectionError(
95+
f"Error while connecting to Podman daemon: {str(e)}"
96+
) from e
8997
except Exception as e:
9098
raise PodmanConnectionError(
91-
message=f"Failed to connect to Podman service: {str(e)}",
92-
environment=os.environ,
93-
host=self.api_kwargs.get("base_url"),
94-
original_error=e,
99+
f"Error while connecting to Podman daemon: {str(e)}"
95100
) from e
96101

97102
def __enter__(self) -> "PodmanClient":
@@ -100,6 +105,18 @@ def __enter__(self) -> "PodmanClient":
100105
def __exit__(self, exc_type, exc_value, traceback) -> None:
101106
self.close()
102107

108+
def __enter__(self) -> "PodmanClient":
109+
return self
110+
111+
def __exit__(self, exc_type, exc_value, traceback) -> None:
112+
self.close()
113+
114+
def __enter__(self) -> "PodmanClient":
115+
return self
116+
117+
def __exit__(self, exc_type, exc_value, traceback) -> None:
118+
self.close()
119+
103120
@classmethod
104121
def from_env(
105122
cls,
@@ -137,41 +154,26 @@ def from_env(
137154
Raises:
138155
ValueError when required environment variable is not set
139156
"""
140-
try:
141-
environment = environment or os.environ
142-
credstore_env = credstore_env or {}
143-
144-
if version == "auto":
145-
version = None
146-
147-
kwargs = {
148-
"version": version,
149-
"timeout": timeout,
150-
"tls": False,
151-
"credstore_env": credstore_env,
152-
"max_pool_size": max_pool_size,
153-
}
154-
155-
host = environment.get("CONTAINER_HOST") or environment.get("DOCKER_HOST") or None
156-
if host is not None:
157-
kwargs["base_url"] = host
158-
159-
return PodmanClient(**kwargs)
160-
except ValueError as e:
161-
error_msg = "Invalid environment configuration for Podman client"
162-
raise PodmanConnectionError(
163-
message=error_msg, environment=environment, host=host, original_error=e
164-
)
165-
except (ConnectionError, TimeoutError) as e:
166-
error_msg = "Failed to connect to Podman service"
167-
raise PodmanConnectionError(
168-
message=error_msg, environment=environment, host=host, original_error=e
169-
)
170-
except Exception as e:
171-
error_msg = "Failed to initialize Podman client from environment"
172-
raise PodmanConnectionError(
173-
message=error_msg, environment=environment, host=host, original_error=e
174-
)
157+
environment = environment or os.environ
158+
credstore_env = credstore_env or {}
159+
160+
if version == "auto":
161+
version = None
162+
163+
kwargs = {
164+
'version': version,
165+
'timeout': timeout,
166+
'tls': False,
167+
'credstore_env': credstore_env,
168+
'max_pool_size': max_pool_size,
169+
}
170+
171+
host = environment.get("CONTAINER_HOST") or environment.get("DOCKER_HOST") or None
172+
if host is not None:
173+
kwargs['base_url'] = host
174+
175+
return PodmanClient(**kwargs)
176+
175177

176178
@cached_property
177179
def containers(self) -> ContainersManager:

podman/errors/exceptions.py

-50
Original file line numberDiff line numberDiff line change
@@ -148,56 +148,6 @@ class InvalidArgument(PodmanError):
148148
class PodmanConnectionError(PodmanError):
149149
"""Exception raised when connection to Podman service fails using environment configuration."""
150150

151-
def __init__(
152-
self,
153-
message: str,
154-
environment: Optional[dict[str, str]] = None,
155-
host: Optional[str] = None,
156-
original_error: Optional[Exception] = None,
157-
):
158-
"""Initialize PodmanConnectionError.
159-
Args:
160-
message: Description of the error
161-
environment: Environment variables used in connection attempt
162-
host: URL to Podman service that failed
163-
original_error: Original exception that caused this error
164-
"""
165-
super().__init__(message)
166-
self.environment = environment
167-
self.host = host
168-
self.original_error = original_error
169-
170-
def __str__(self) -> str:
171-
"""Format error message with details about connection attempt."""
172-
msg = [super().__str__()]
173-
174-
if self.host:
175-
msg.append(f"Host: {self.host}")
176-
177-
if self.environment:
178-
relevant_vars = {
179-
k: v
180-
for k, v in self.environment.items()
181-
if k
182-
in (
183-
'DOCKER_HOST',
184-
'CONTAINER_HOST',
185-
'DOCKER_TLS_VERIFY',
186-
'CONTAINER_TLS_VERIFY',
187-
'DOCKER_CERT_PATH',
188-
'CONTAINER_CERT_PATH',
189-
)
190-
}
191-
if relevant_vars:
192-
msg.append("Environment:")
193-
for key, value in relevant_vars.items():
194-
msg.append(f" {key}={value}")
195-
196-
if self.original_error:
197-
msg.append(f"Caused by: {str(self.original_error)}")
198-
199-
return " | ".join(msg)
200-
201151

202152
class StreamParseError(RuntimeError):
203153
def __init__(self, reason):

0 commit comments

Comments
 (0)