Skip to content

Commit 03abe45

Browse files
authored
Add duplicate lease exception (#22)
1 parent 56faa00 commit 03abe45

File tree

4 files changed

+41
-2
lines changed

4 files changed

+41
-2
lines changed

aetcd/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from .exceptions import ClientError # noqa: F401
66
from .exceptions import ConnectionFailedError # noqa: F401
77
from .exceptions import ConnectionTimeoutError # noqa: F401
8+
from .exceptions import DuplicateLeaseError # noqa: F401
89
from .exceptions import InternalError # noqa: F401
910
from .exceptions import InvalidArgumentError # noqa: F401
1011
from .exceptions import PreconditionFailedError # noqa: F401

aetcd/exceptions.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class PreconditionFailedError(ClientError):
2929
"""Raises on etcd server precondition errors."""
3030

3131

32+
class DuplicateLeaseError(ClientError):
33+
"""Raised on attempt to create lease with already existing id."""
34+
35+
3236
class RevisionCompactedError(ClientError):
3337
"""Raises when requested and previous revisions were already compacted."""
3438

@@ -68,9 +72,13 @@ def _handle_exception(error: Exception):
6872
# Query RPC error mapping and raise one of the matched client errors
6973
if isinstance(error, rpc.AioRpcError):
7074
e = _EXCEPTIONS_BY_CODE.get(error.code())
75+
error_details = error.details()
76+
7177
if e is not None:
72-
raise e(error.details()) from error
73-
raise ClientError(error.details()) from error
78+
if e is PreconditionFailedError and 'lease already exists' in error_details:
79+
raise DuplicateLeaseError
80+
raise e(error_details) from error
81+
raise ClientError(error_details) from error
7482

7583
# Fallback to wrap original error with the client error
7684
raise ClientError(error)

tests/integration/test_lease.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import pytest
44

5+
import aetcd.exceptions
6+
57

68
@pytest.mark.asyncio
79
async def test_lease_grant(etcd):
@@ -44,3 +46,11 @@ async def test_lease_expire(etcd):
4446
await asyncio.sleep((await lease.granted_ttl()) + 1)
4547
result = await etcd.get(key)
4648
assert result is None
49+
50+
51+
@pytest.mark.asyncio
52+
async def test_lease_create_with_already_existing_id(etcd):
53+
await etcd.lease(10, lease_id=123)
54+
55+
with pytest.raises(aetcd.exceptions.DuplicateLeaseError):
56+
await etcd.lease(15, lease_id=123)

tests/test_exceptions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,23 @@ def test__handle_exception_with_unknown_errors(rpc_error):
6767

6868
with pytest.raises(aetcd.exceptions.ClientError, match='unknown error'):
6969
aetcd.exceptions._handle_exception(error)
70+
71+
72+
def test__handle_exception_with_duplicate_lease_error(rpc_error):
73+
error = rpc_error(
74+
code=aetcd.rpc.StatusCode.FAILED_PRECONDITION,
75+
details='etcdserver: lease already exists',
76+
)
77+
78+
with pytest.raises(aetcd.exceptions.DuplicateLeaseError):
79+
aetcd.exceptions._handle_exception(error)
80+
81+
82+
def test__handle_exception_with_duplicate_lease_error_and_internal_rpc_error(rpc_error):
83+
error = rpc_error(
84+
code=aetcd.rpc.StatusCode.INTERNAL,
85+
details='etcdserver: lease already exists',
86+
)
87+
88+
with pytest.raises(aetcd.exceptions.InternalError):
89+
aetcd.exceptions._handle_exception(error)

0 commit comments

Comments
 (0)