2022-04-09 21:45:25 +00:00
import json
from moto . core . exceptions import JsonRESTError
2022-03-09 16:57:25 -01:00
from moto . dynamodb . limits import HASH_KEY_MAX_LENGTH , RANGE_KEY_MAX_LENGTH
2021-04-30 22:47:47 +10:00
2022-04-09 21:45:25 +00:00
class DynamodbException ( JsonRESTError ) :
2019-05-22 01:45:30 +09:00
pass
2019-10-09 17:25:50 +01:00
2022-04-09 21:45:25 +00:00
class MockValidationException ( DynamodbException ) :
error_type = " com.amazonaws.dynamodb.v20111205#ValidationException "
2020-04-11 11:07:22 +01:00
def __init__ ( self , message ) :
2022-04-09 21:45:25 +00:00
super ( ) . __init__ ( MockValidationException . error_type , message = message )
2020-04-11 11:07:22 +01:00
self . exception_msg = message
2022-04-09 21:45:25 +00:00
class InvalidIndexNameError ( MockValidationException ) :
pass
2020-04-19 16:38:29 +01:00
class InvalidUpdateExpressionInvalidDocumentPath ( MockValidationException ) :
2020-04-11 11:07:22 +01:00
invalid_update_expression_msg = (
" The document path provided in the update expression is invalid for update "
)
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . invalid_update_expression_msg )
2020-04-11 11:07:22 +01:00
2020-04-19 16:38:29 +01:00
class InvalidUpdateExpression ( MockValidationException ) :
invalid_update_expr_msg = " Invalid UpdateExpression: {update_expression_error} "
def __init__ ( self , update_expression_error ) :
self . update_expression_error = update_expression_error
2021-12-28 21:26:56 -01:00
super ( ) . __init__ (
2020-04-19 16:38:29 +01:00
self . invalid_update_expr_msg . format (
update_expression_error = update_expression_error
)
)
2022-01-25 19:26:11 +09:00
class InvalidConditionExpression ( MockValidationException ) :
invalid_condition_expr_msg = (
" Invalid ConditionExpression: {condition_expression_error} "
)
def __init__ ( self , condition_expression_error ) :
self . condition_expression_error = condition_expression_error
super ( ) . __init__ (
self . invalid_condition_expr_msg . format (
condition_expression_error = condition_expression_error
)
)
class ConditionAttributeIsReservedKeyword ( InvalidConditionExpression ) :
attribute_is_keyword_msg = (
" Attribute name is a reserved keyword; reserved keyword: {keyword} "
)
def __init__ ( self , keyword ) :
self . keyword = keyword
super ( ) . __init__ ( self . attribute_is_keyword_msg . format ( keyword = keyword ) )
2020-04-19 16:38:29 +01:00
class AttributeDoesNotExist ( MockValidationException ) :
attr_does_not_exist_msg = (
" The provided expression refers to an attribute that does not exist in the item "
2020-04-11 11:07:22 +01:00
)
2020-04-19 16:38:29 +01:00
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . attr_does_not_exist_msg )
2020-04-19 16:38:29 +01:00
2020-04-26 15:12:33 +01:00
class ProvidedKeyDoesNotExist ( MockValidationException ) :
provided_key_does_not_exist_msg = (
" The provided key element does not match the schema "
)
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . provided_key_does_not_exist_msg )
2020-04-26 15:12:33 +01:00
2020-04-19 16:38:29 +01:00
class ExpressionAttributeNameNotDefined ( InvalidUpdateExpression ) :
name_not_defined_msg = " An expression attribute name used in the document path is not defined; attribute name: {n} "
def __init__ ( self , attribute_name ) :
self . not_defined_attribute_name = attribute_name
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . name_not_defined_msg . format ( n = attribute_name ) )
2020-04-19 16:38:29 +01:00
class AttributeIsReservedKeyword ( InvalidUpdateExpression ) :
attribute_is_keyword_msg = (
" Attribute name is a reserved keyword; reserved keyword: {keyword} "
)
def __init__ ( self , keyword ) :
self . keyword = keyword
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . attribute_is_keyword_msg . format ( keyword = keyword ) )
2020-04-19 16:38:29 +01:00
class ExpressionAttributeValueNotDefined ( InvalidUpdateExpression ) :
attr_value_not_defined_msg = " An expression attribute value used in expression is not defined; attribute value: {attribute_value} "
def __init__ ( self , attribute_value ) :
self . attribute_value = attribute_value
2021-12-28 21:26:56 -01:00
super ( ) . __init__ (
2020-04-19 16:38:29 +01:00
self . attr_value_not_defined_msg . format ( attribute_value = attribute_value )
)
class UpdateExprSyntaxError ( InvalidUpdateExpression ) :
update_expr_syntax_error_msg = " Syntax error; {error_detail} "
2020-04-11 11:07:22 +01:00
def __init__ ( self , error_detail ) :
self . error_detail = error_detail
2021-12-28 21:26:56 -01:00
super ( ) . __init__ (
2020-04-11 11:07:22 +01:00
self . update_expr_syntax_error_msg . format ( error_detail = error_detail )
)
class InvalidTokenException ( UpdateExprSyntaxError ) :
token_detail_msg = ' token: " {token} " , near: " {near} " '
def __init__ ( self , token , near ) :
self . token = token
self . near = near
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . token_detail_msg . format ( token = token , near = near ) )
2020-04-11 11:07:22 +01:00
class InvalidExpressionAttributeNameKey ( MockValidationException ) :
invalid_expr_attr_name_msg = (
' ExpressionAttributeNames contains invalid key: Syntax error; key: " {key} " '
)
def __init__ ( self , key ) :
self . key = key
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . invalid_expr_attr_name_msg . format ( key = key ) )
2020-04-11 11:07:22 +01:00
2019-10-14 10:02:22 +01:00
2020-04-11 11:07:22 +01:00
class ItemSizeTooLarge ( MockValidationException ) :
item_size_too_large_msg = " Item size has exceeded the maximum allowed size "
2019-10-14 10:02:22 +01:00
2020-04-11 11:07:22 +01:00
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . item_size_too_large_msg )
2020-04-19 16:38:29 +01:00
2020-04-19 16:50:53 +01:00
class ItemSizeToUpdateTooLarge ( MockValidationException ) :
item_size_to_update_too_large_msg = (
" Item size to update has exceeded the maximum allowed size "
)
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . item_size_to_update_too_large_msg )
2020-04-19 16:50:53 +01:00
2021-04-30 22:47:47 +10:00
class HashKeyTooLong ( MockValidationException ) :
# deliberately no space between of and {lim}
key_too_large_msg = " One or more parameter values were invalid: Size of hashkey has exceeded the maximum size limit of {lim} bytes " . format (
lim = HASH_KEY_MAX_LENGTH
)
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . key_too_large_msg )
2021-04-30 22:47:47 +10:00
class RangeKeyTooLong ( MockValidationException ) :
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 (
lim = RANGE_KEY_MAX_LENGTH
)
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . key_too_large_msg )
2021-04-30 22:47:47 +10:00
2020-04-19 16:38:29 +01:00
class IncorrectOperandType ( InvalidUpdateExpression ) :
inv_operand_msg = " Incorrect operand type for operator or function; operator or function: {f} , operand type: {t} "
def __init__ ( self , operator_or_function , operand_type ) :
self . operator_or_function = operator_or_function
self . operand_type = operand_type
2021-12-28 21:26:56 -01:00
super ( ) . __init__ (
2020-04-19 16:38:29 +01:00
self . inv_operand_msg . format ( f = operator_or_function , t = operand_type )
)
2020-04-26 15:12:33 +01:00
class IncorrectDataType ( MockValidationException ) :
inc_data_type_msg = " An operand in the update expression has an incorrect data type "
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . inc_data_type_msg )
2020-05-11 15:29:21 +01:00
2022-04-09 21:45:25 +00:00
class ConditionalCheckFailed ( DynamodbException ) :
error_type = " com.amazonaws.dynamodb.v20111205#ConditionalCheckFailedException "
2020-05-11 15:29:21 +01:00
2022-04-09 21:45:25 +00:00
def __init__ ( self , msg = None ) :
super ( ) . __init__ (
ConditionalCheckFailed . error_type , msg or " The conditional request failed "
)
2020-05-11 15:29:21 +01:00
2022-04-09 21:45:25 +00:00
class TransactionCanceledException ( DynamodbException ) :
2020-05-11 15:29:21 +01:00
cancel_reason_msg = " Transaction cancelled, please refer cancellation reasons for specific reasons [ {} ] "
2022-04-09 21:45:25 +00:00
error_type = " com.amazonaws.dynamodb.v20120810#TransactionCanceledException "
2020-05-11 15:29:21 +01:00
def __init__ ( self , errors ) :
2022-04-09 21:45:25 +00:00
msg = self . cancel_reason_msg . format (
2022-09-17 09:50:31 +00:00
" , " . join ( [ str ( code ) for code , _ , _ in errors ] )
2022-04-09 21:45:25 +00:00
)
super ( ) . __init__ (
error_type = TransactionCanceledException . error_type , message = msg
)
reasons = [
2022-09-17 09:50:31 +00:00
{ " Code " : code , " Message " : message , * * item } if code else { " Code " : " None " }
for code , message , item in errors
2022-04-09 21:45:25 +00:00
]
self . description = json . dumps (
{
" __type " : TransactionCanceledException . error_type ,
" CancellationReasons " : reasons ,
" Message " : msg ,
}
)
2020-11-17 01:12:39 -08:00
2022-01-25 19:26:39 +09:00
class MultipleTransactionsException ( MockValidationException ) :
msg = " Transaction request cannot include multiple operations on one item "
def __init__ ( self ) :
super ( ) . __init__ ( self . msg )
2022-02-10 19:09:45 -01:00
class TooManyTransactionsException ( MockValidationException ) :
msg = " Validation error at transactItems: Member must have length less than or equal to 25. "
def __init__ ( self ) :
super ( ) . __init__ ( self . msg )
2020-11-17 01:12:39 -08:00
class EmptyKeyAttributeException ( MockValidationException ) :
empty_str_msg = " One or more parameter values were invalid: An AttributeValue may not contain an empty string "
2021-10-09 21:02:53 +00:00
# AWS has a different message for empty index keys
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. "
2020-11-17 01:12:39 -08:00
2021-10-09 21:02:53 +00:00
def __init__ ( self , key_in_index = False ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . empty_index_msg if key_in_index else self . empty_str_msg )
2021-10-09 21:02:53 +00:00
class UpdateHashRangeKeyException ( MockValidationException ) :
msg = " One or more parameter values were invalid: Cannot update attribute {} . This attribute is part of the key "
def __init__ ( self , key_name ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . msg . format ( key_name ) )
2021-10-12 19:32:10 +00:00
2021-11-10 20:42:33 -01:00
class InvalidAttributeTypeError ( MockValidationException ) :
msg = " One or more parameter values were invalid: Type mismatch for key {} expected: {} actual: {} "
def __init__ ( self , name , expected_type , actual_type ) :
super ( ) . __init__ ( self . msg . format ( name , expected_type , actual_type ) )
2022-09-30 10:07:20 +00:00
class DuplicateUpdateExpression ( InvalidUpdateExpression ) :
def __init__ ( self , names ) :
super ( ) . __init__ (
f " Two document paths overlap with each other; must remove or rewrite one of these paths; path one: [ { names [ 0 ] } ], path two: [ { names [ 1 ] } ] "
)
2021-10-12 19:32:10 +00:00
class TooManyAddClauses ( InvalidUpdateExpression ) :
msg = ' The " ADD " section can only be used once in an update expression; '
def __init__ ( self ) :
2021-12-28 21:26:56 -01:00
super ( ) . __init__ ( self . msg )
2022-04-09 21:45:25 +00:00
class ResourceNotFoundException ( JsonRESTError ) :
def __init__ ( self , msg = None ) :
err = " com.amazonaws.dynamodb.v20111205#ResourceNotFoundException "
super ( ) . __init__ ( err , msg or " Requested resource not found " )
class TableNotFoundException ( JsonRESTError ) :
def __init__ ( self , name ) :
err = " com.amazonaws.dynamodb.v20111205#TableNotFoundException "
msg = " Table not found: {} " . format ( name )
super ( ) . __init__ ( err , msg )
class SourceTableNotFoundException ( JsonRESTError ) :
def __init__ ( self , source_table_name ) :
er = " com.amazonaws.dynamodb.v20111205#SourceTableNotFoundException "
super ( ) . __init__ ( er , " Source table not found: %s " % source_table_name )
class BackupNotFoundException ( JsonRESTError ) :
def __init__ ( self , backup_arn ) :
er = " com.amazonaws.dynamodb.v20111205#BackupNotFoundException "
super ( ) . __init__ ( er , " Backup not found: %s " % backup_arn )
class TableAlreadyExistsException ( JsonRESTError ) :
def __init__ ( self , target_table_name ) :
er = " com.amazonaws.dynamodb.v20111205#TableAlreadyExistsException "
super ( ) . __init__ ( er , " Table already exists: %s " % target_table_name )
class ResourceInUseException ( JsonRESTError ) :
def __init__ ( self ) :
er = " com.amazonaws.dynamodb.v20111205#ResourceInUseException "
super ( ) . __init__ ( er , " Resource in use " )
class StreamAlreadyEnabledException ( JsonRESTError ) :
def __init__ ( self ) :
er = " com.amazonaws.dynamodb.v20111205#ResourceInUseException "
super ( ) . __init__ ( er , " Cannot enable stream " )
2022-05-09 13:01:31 +00:00
class InvalidConversion ( JsonRESTError ) :
def __init__ ( self ) :
er = " SerializationException "
super ( ) . __init__ ( er , " NUMBER_VALUE cannot be converted to String " )