1from moto.dynamodb2.limits import HASH_KEY_MAX_LENGTH, RANGE_KEY_MAX_LENGTH 2 3 4class InvalidIndexNameError(ValueError): 5 pass 6 7 8class MockValidationException(ValueError): 9 def __init__(self, message): 10 self.exception_msg = message 11 12 13class InvalidUpdateExpressionInvalidDocumentPath(MockValidationException): 14 invalid_update_expression_msg = ( 15 "The document path provided in the update expression is invalid for update" 16 ) 17 18 def __init__(self): 19 super(InvalidUpdateExpressionInvalidDocumentPath, self).__init__( 20 self.invalid_update_expression_msg 21 ) 22 23 24class InvalidUpdateExpression(MockValidationException): 25 invalid_update_expr_msg = "Invalid UpdateExpression: {update_expression_error}" 26 27 def __init__(self, update_expression_error): 28 self.update_expression_error = update_expression_error 29 super(InvalidUpdateExpression, self).__init__( 30 self.invalid_update_expr_msg.format( 31 update_expression_error=update_expression_error 32 ) 33 ) 34 35 36class AttributeDoesNotExist(MockValidationException): 37 attr_does_not_exist_msg = ( 38 "The provided expression refers to an attribute that does not exist in the item" 39 ) 40 41 def __init__(self): 42 super(AttributeDoesNotExist, self).__init__(self.attr_does_not_exist_msg) 43 44 45class ProvidedKeyDoesNotExist(MockValidationException): 46 provided_key_does_not_exist_msg = ( 47 "The provided key element does not match the schema" 48 ) 49 50 def __init__(self): 51 super(ProvidedKeyDoesNotExist, self).__init__( 52 self.provided_key_does_not_exist_msg 53 ) 54 55 56class ExpressionAttributeNameNotDefined(InvalidUpdateExpression): 57 name_not_defined_msg = "An expression attribute name used in the document path is not defined; attribute name: {n}" 58 59 def __init__(self, attribute_name): 60 self.not_defined_attribute_name = attribute_name 61 super(ExpressionAttributeNameNotDefined, self).__init__( 62 self.name_not_defined_msg.format(n=attribute_name) 63 ) 64 65 66class AttributeIsReservedKeyword(InvalidUpdateExpression): 67 attribute_is_keyword_msg = ( 68 "Attribute name is a reserved keyword; reserved keyword: {keyword}" 69 ) 70 71 def __init__(self, keyword): 72 self.keyword = keyword 73 super(AttributeIsReservedKeyword, self).__init__( 74 self.attribute_is_keyword_msg.format(keyword=keyword) 75 ) 76 77 78class ExpressionAttributeValueNotDefined(InvalidUpdateExpression): 79 attr_value_not_defined_msg = "An expression attribute value used in expression is not defined; attribute value: {attribute_value}" 80 81 def __init__(self, attribute_value): 82 self.attribute_value = attribute_value 83 super(ExpressionAttributeValueNotDefined, self).__init__( 84 self.attr_value_not_defined_msg.format(attribute_value=attribute_value) 85 ) 86 87 88class UpdateExprSyntaxError(InvalidUpdateExpression): 89 update_expr_syntax_error_msg = "Syntax error; {error_detail}" 90 91 def __init__(self, error_detail): 92 self.error_detail = error_detail 93 super(UpdateExprSyntaxError, self).__init__( 94 self.update_expr_syntax_error_msg.format(error_detail=error_detail) 95 ) 96 97 98class InvalidTokenException(UpdateExprSyntaxError): 99 token_detail_msg = 'token: "{token}", near: "{near}"' 100 101 def __init__(self, token, near): 102 self.token = token 103 self.near = near 104 super(InvalidTokenException, self).__init__( 105 self.token_detail_msg.format(token=token, near=near) 106 ) 107 108 109class InvalidExpressionAttributeNameKey(MockValidationException): 110 invalid_expr_attr_name_msg = ( 111 'ExpressionAttributeNames contains invalid key: Syntax error; key: "{key}"' 112 ) 113 114 def __init__(self, key): 115 self.key = key 116 super(InvalidExpressionAttributeNameKey, self).__init__( 117 self.invalid_expr_attr_name_msg.format(key=key) 118 ) 119 120 121class ItemSizeTooLarge(MockValidationException): 122 item_size_too_large_msg = "Item size has exceeded the maximum allowed size" 123 124 def __init__(self): 125 super(ItemSizeTooLarge, self).__init__(self.item_size_too_large_msg) 126 127 128class ItemSizeToUpdateTooLarge(MockValidationException): 129 item_size_to_update_too_large_msg = ( 130 "Item size to update has exceeded the maximum allowed size" 131 ) 132 133 def __init__(self): 134 super(ItemSizeToUpdateTooLarge, self).__init__( 135 self.item_size_to_update_too_large_msg 136 ) 137 138 139class HashKeyTooLong(MockValidationException): 140 # deliberately no space between of and {lim} 141 key_too_large_msg = "One or more parameter values were invalid: Size of hashkey has exceeded the maximum size limit of{lim} bytes".format( 142 lim=HASH_KEY_MAX_LENGTH 143 ) 144 145 def __init__(self): 146 super(HashKeyTooLong, self).__init__(self.key_too_large_msg) 147 148 149class RangeKeyTooLong(MockValidationException): 150 key_too_large_msg = "One or more parameter values were invalid: Aggregated size of all range keys has exceeded the size limit of {lim} bytes".format( 151 lim=RANGE_KEY_MAX_LENGTH 152 ) 153 154 def __init__(self): 155 super(RangeKeyTooLong, self).__init__(self.key_too_large_msg) 156 157 158class IncorrectOperandType(InvalidUpdateExpression): 159 inv_operand_msg = "Incorrect operand type for operator or function; operator or function: {f}, operand type: {t}" 160 161 def __init__(self, operator_or_function, operand_type): 162 self.operator_or_function = operator_or_function 163 self.operand_type = operand_type 164 super(IncorrectOperandType, self).__init__( 165 self.inv_operand_msg.format(f=operator_or_function, t=operand_type) 166 ) 167 168 169class IncorrectDataType(MockValidationException): 170 inc_data_type_msg = "An operand in the update expression has an incorrect data type" 171 172 def __init__(self): 173 super(IncorrectDataType, self).__init__(self.inc_data_type_msg) 174 175 176class ConditionalCheckFailed(ValueError): 177 msg = "The conditional request failed" 178 179 def __init__(self): 180 super(ConditionalCheckFailed, self).__init__(self.msg) 181 182 183class TransactionCanceledException(ValueError): 184 cancel_reason_msg = "Transaction cancelled, please refer cancellation reasons for specific reasons [{}]" 185 186 def __init__(self, errors): 187 msg = self.cancel_reason_msg.format(", ".join([str(err) for err in errors])) 188 super(TransactionCanceledException, self).__init__(msg) 189 190 191class EmptyKeyAttributeException(MockValidationException): 192 empty_str_msg = "One or more parameter values were invalid: An AttributeValue may not contain an empty string" 193 # AWS has a different message for empty index keys 194 empty_index_msg = "One or more parameter values are not valid. The update expression attempted to update a secondary index key to a value that is not supported. The AttributeValue for a key attribute cannot contain an empty string value." 195 196 def __init__(self, key_in_index=False): 197 super(EmptyKeyAttributeException, self).__init__( 198 self.empty_index_msg if key_in_index else self.empty_str_msg 199 ) 200 201 202class UpdateHashRangeKeyException(MockValidationException): 203 msg = "One or more parameter values were invalid: Cannot update attribute {}. This attribute is part of the key" 204 205 def __init__(self, key_name): 206 super(UpdateHashRangeKeyException, self).__init__(self.msg.format(key_name)) 207 208 209class InvalidAttributeTypeError(MockValidationException): 210 msg = "One or more parameter values were invalid: Type mismatch for key {} expected: {} actual: {}" 211 212 def __init__(self, name, expected_type, actual_type): 213 super().__init__(self.msg.format(name, expected_type, actual_type)) 214 215 216class TooManyAddClauses(InvalidUpdateExpression): 217 msg = 'The "ADD" section can only be used once in an update expression;' 218 219 def __init__(self): 220 super(TooManyAddClauses, self).__init__(self.msg) 221