Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions hcloud/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@


class HCloudException(Exception):
"""There was an error while using the hcloud library"""
"""There was an error while using the hcloud library.

All exceptions in the hcloud library inherit from this exception. It may be used as
catch-all exception.
"""


class APIException(HCloudException):
"""There was an error while performing an API Request"""
"""There was an error while performing an API Request."""

def __init__(
self,
Expand Down
15 changes: 14 additions & 1 deletion hcloud/actions/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,22 @@ class ActionException(HCloudException):
def __init__(self, action: Action | BoundAction):
assert self.__doc__ is not None
message = self.__doc__
if action.error is not None and "message" in action.error:

extras = []
if (
action.error is not None
and "code" in action.error
and "message" in action.error
):
message += f": {action.error['message']}"

extras.append(action.error["code"])
else:
extras.append(action.command)

extras.append(str(action.id))
message += f" ({', '.join(extras)})"

super().__init__(message)
self.message = message
self.action = action
Expand Down
62 changes: 62 additions & 0 deletions tests/unit/test_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from __future__ import annotations

import pytest

from hcloud import (
APIException,
HCloudException,
)
from hcloud.actions import Action, ActionFailedException, ActionTimeoutException

running_action = Action(
id=12345,
command="action_command",
status=Action.STATUS_RUNNING,
)

failed_action = Action(
id=12345,
command="action_command",
status=Action.STATUS_ERROR,
error={"code": "action_failed", "message": "Action failed"},
)


@pytest.mark.parametrize(
("exception", "expected"),
[
(
# Should never be raised by itself
HCloudException(),
"",
),
(
# Should never be raised by itself
HCloudException("A test error"),
"A test error",
),
(
APIException(code="conflict", message="API error message", details=None),
"API error message (conflict)",
),
(
APIException(
code="conflict",
message="API error message",
details=None,
correlation_id="fddea8fabd02fb21",
),
"API error message (conflict, fddea8fabd02fb21)",
),
(
ActionFailedException(failed_action),
"The pending action failed: Action failed (action_failed, 12345)",
),
(
ActionTimeoutException(running_action),
"The pending action timed out (action_command, 12345)",
),
],
)
def test_exceptions(exception, expected):
assert str(exception) == expected