• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pynamodb / PynamoDB / 15032044705

14 May 2025 10:06PM UTC coverage: 94.865%. Remained the same
15032044705

Pull #1267

github

web-flow
Merge f1764b7d7 into 3a5ee1492
Pull Request #1267: chore(docs): remove default region reference in docs

2845 of 2999 relevant lines covered (94.86%)

6.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.9
/pynamodb/exceptions.py
1
"""
2
PynamoDB exceptions
3
"""
4
import sys
7✔
5
from dataclasses import dataclass
7✔
6
from typing import Any
7✔
7
from typing import Dict
7✔
8
from typing import Iterable
7✔
9
from typing import List
7✔
10
from typing import Optional
7✔
11
if sys.version_info >= (3, 8):
7✔
12
    from typing import Literal
6✔
13
else:
14
    from typing_extensions import Literal
1✔
15

16
import botocore.exceptions
7✔
17

18

19
class PynamoDBException(Exception):
7✔
20
    """
21
    Base class for all PynamoDB exceptions.
22
    """
23

24
    msg: str
7✔
25

26
    def __init__(self, msg: Optional[str] = None, cause: Optional[Exception] = None) -> None:
7✔
27
        self.msg = msg if msg is not None else self.msg
7✔
28
        self.cause = cause
7✔
29
        super(PynamoDBException, self).__init__(self.msg)
7✔
30

31
    @property
7✔
32
    def cause_response_code(self) -> Optional[str]:
7✔
33
        """
34
        The DynamoDB response code such as:
35

36
        - ``ConditionalCheckFailedException``
37
        - ``ProvisionedThroughputExceededException``
38
        - ``TransactionCanceledException``
39

40
        Inspect this value to determine the cause of the error and handle it.
41
        """
42
        return getattr(self.cause, 'response', {}).get('Error', {}).get('Code')
7✔
43

44
    @property
7✔
45
    def cause_response_message(self) -> Optional[str]:
7✔
46
        """
47
        The human-readable description of the error returned by DynamoDB.
48
        """
49
        return getattr(self.cause, 'response', {}).get('Error', {}).get('Message')
7✔
50

51

52
class PynamoDBConnectionError(PynamoDBException):
7✔
53
    """
54
    A base class for connection errors
55
    """
56
    msg = "Connection Error"
7✔
57

58

59
class DeleteError(PynamoDBConnectionError):
7✔
60
    """
61
    Raised when an error occurs deleting an item
62
    """
63
    msg = "Error deleting item"
7✔
64

65

66
class QueryError(PynamoDBConnectionError):
7✔
67
    """
68
    Raised when queries fail
69
    """
70
    msg = "Error performing query"
7✔
71

72

73
class ScanError(PynamoDBConnectionError):
7✔
74
    """
75
    Raised when a scan operation fails
76
    """
77
    msg = "Error performing scan"
7✔
78

79

80
class PutError(PynamoDBConnectionError):
7✔
81
    """
82
    Raised when an item fails to be created
83
    """
84
    msg = "Error putting item"
7✔
85

86

87
class UpdateError(PynamoDBConnectionError):
7✔
88
    """
89
    Raised when an item fails to be updated
90
    """
91
    msg = "Error updating item"
7✔
92

93

94
class GetError(PynamoDBConnectionError):
7✔
95
    """
96
    Raised when an item fails to be retrieved
97
    """
98
    msg = "Error getting item"
7✔
99

100

101
class TableError(PynamoDBConnectionError):
7✔
102
    """
103
    An error involving a dynamodb table operation
104
    """
105
    msg = "Error performing a table operation"
7✔
106

107

108
class DoesNotExist(PynamoDBException):
7✔
109
    """
110
    Raised when an item queried does not exist
111
    """
112
    msg = "Item does not exist"
7✔
113

114

115
class TableDoesNotExist(PynamoDBException):
7✔
116
    """
117
    Raised when an operation is attempted on a table that doesn't exist
118
    """
119
    def __init__(self, table_name: str) -> None:
7✔
120
        msg = "Table does not exist: `{}`".format(table_name)
7✔
121
        super(TableDoesNotExist, self).__init__(msg)
7✔
122

123

124
@dataclass
7✔
125
class CancellationReason:
6✔
126
    """
127
    A reason for a transaction cancellation.
128
    
129
    For a list of possible cancellation reasons and their semantics,
130
    see `TransactGetItems`_ and `TransactWriteItems`_ in the AWS documentation.
131

132
    .. _TransactGetItems: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html
133
    .. _TransactWriteItems: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html
134
    """
135
    code: str
7✔
136
    message: Optional[str] = None
7✔
137
    raw_item: Optional[Dict[str, Dict[str, Any]]] = None
7✔
138

139

140
class TransactWriteError(PynamoDBException):
7✔
141
    """
142
    Raised when a :class:`~pynamodb.transactions.TransactWrite` operation fails.
143
    """
144

145
    @property
7✔
146
    def cancellation_reasons(self) -> List[Optional[CancellationReason]]:
7✔
147
        """
148
        When :attr:`.cause_response_code` is ``TransactionCanceledException``, this property lists
149
        cancellation reasons in the same order as the transaction items (one-to-one).
150
        Items which were not part of the reason for cancellation would have :code:`None` as the value.
151

152
        For a list of possible cancellation reasons and their semantics,
153
        see `TransactWriteItems`_ in the AWS documentation.
154

155
        .. _TransactWriteItems: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html
156
        """
157
        if not isinstance(self.cause, VerboseClientError):
7✔
158
            return []
×
159
        return self.cause.cancellation_reasons
7✔
160

161

162
class TransactGetError(PynamoDBException):
7✔
163
    """
164
    Raised when a :class:`~pynamodb.transactions.TransactGet` operation fails.
165
    """
166
    @property
7✔
167
    def cancellation_reasons(self) -> List[Optional[CancellationReason]]:
7✔
168
        """
169
        When :attr:`.cause_response_code` is ``TransactionCanceledException``, this property lists
170
        cancellation reasons in the same order as the transaction items (one-to-one).
171
        Items which were not part of the reason for cancellation would have :code:`None` as the value.
172

173
        For a list of possible cancellation reasons and their semantics,
174
        see `TransactGetItems`_ in the AWS documentation.
175

176
        .. _TransactGetItems: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html
177
        """
178
        if not isinstance(self.cause, VerboseClientError):
×
179
            return []
×
180
        return self.cause.cancellation_reasons
×
181

182

183
class InvalidStateError(PynamoDBException):
7✔
184
    """
185
    Raises when the internal state of an operation context is invalid.
186
    """
187
    msg = "Operation in invalid state"
7✔
188

189

190
class AttributeDeserializationError(TypeError):
7✔
191
    """
192
    Raised when attribute type is invalid during deserialization.
193
    """
194
    def __init__(self, attr_name: str, attr_type: str):
7✔
195
        msg = "Cannot deserialize '{}' attribute from type: {}".format(attr_name, attr_type)
7✔
196
        super(AttributeDeserializationError, self).__init__(msg)
7✔
197

198

199
class AttributeNullError(ValueError):
7✔
200
    """
201
    Raised when an attribute which is not nullable (:code:`null=False`) is unset during serialization.
202
    """
203

204
    def __init__(self, attr_name: str) -> None:
7✔
205
        self.attr_path = attr_name
7✔
206

207
    def __str__(self):
7✔
208
        return f"Attribute '{self.attr_path}' cannot be None"
7✔
209

210
    def prepend_path(self, attr_name: str) -> None:
7✔
211
        self.attr_path = attr_name + '.' + self.attr_path
7✔
212

213

214
class VerboseClientError(botocore.exceptions.ClientError):
7✔
215
    def __init__(
7✔
216
        self,
217
        error_response: Dict[str, Any],
218
        operation_name: str,
219
        verbose_properties: Optional[Any] = None,
220
        *,
221
        cancellation_reasons: Iterable[Optional[CancellationReason]] = (),
222
    ) -> None:
223
        """
224
        Like ClientError, but with a verbose message.
225

226
        :param error_response: Error response in shape expected by ClientError.
227
        :param operation_name: The name of the operation that failed.
228
        :param verbose_properties: A dict of properties to include in the verbose message.
229
        :param cancellation_reasons: For `TransactionCanceledException` error code,
230
          a list of cancellation reasons in the same order as the transaction's items (one to one).
231
          For items which were not a reason for the transaction cancellation, :code:`None` will be the value.
232
        """
233
        if not verbose_properties:
7✔
234
            verbose_properties = {}
×
235

236
        self.MSG_TEMPLATE = (
7✔
237
            'An error occurred ({{error_code}}) on request ({request_id}) '
238
            'on table ({table_name}) when calling the {{operation_name}} '
239
            'operation: {{error_message}}'
240
        ).format(request_id=verbose_properties.get('request_id'), table_name=verbose_properties.get('table_name'))
241

242
        self.cancellation_reasons = list(cancellation_reasons)
7✔
243

244
        super(VerboseClientError, self).__init__(
7✔
245
            error_response,  # type:ignore[arg-type]  # in stubs: botocore.exceptions._ClientErrorResponseTypeDef
246
            operation_name,
247
        )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc