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
18 changes: 15 additions & 3 deletions src/momento/_cache_service_errors_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@
from . import _momento_logger

__rpc_to_error = {
grpc.StatusCode.ALREADY_EXISTS: errors.CacheExistsError,
grpc.StatusCode.INVALID_ARGUMENT: errors.CacheValueError,
grpc.StatusCode.NOT_FOUND: errors.CacheNotFoundError,
grpc.StatusCode.INVALID_ARGUMENT: errors.BadRequestError,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be errors.InvalidArgumentError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. These are the naming conventions we will be following
https://www.notion.so/momentohq/GRPC-Status-Code-Mapping-35f76a4abc634e26b1129a649e1b329d

The second column:
BadRequest*

For SDK client side checks we will be using
InvalidArgument*

grpc.StatusCode.OUT_OF_RANGE: errors.BadRequestError,
grpc.StatusCode.UNIMPLEMENTED: errors.BadRequestError,
grpc.StatusCode.FAILED_PRECONDITION: errors.BadRequestError,
grpc.StatusCode.CANCELLED: errors.CancelledError,
grpc.StatusCode.DEADLINE_EXCEEDED: errors.TimeoutError,
grpc.StatusCode.PERMISSION_DENIED: errors.PermissionError,
grpc.StatusCode.UNAUTHENTICATED: errors.AuthenticationError,
grpc.StatusCode.RESOURCE_EXHAUSTED: errors.LimitExceededError,
grpc.StatusCode.ALREADY_EXISTS: errors.AlreadyExistsError,
grpc.StatusCode.NOT_FOUND: errors.NotFoundError,
grpc.StatusCode.UNKNOWN: errors.InternalServerError,
grpc.StatusCode.ABORTED: errors.InternalServerError,
grpc.StatusCode.INTERNAL: errors.InternalServerError,
grpc.StatusCode.UNAVAILABLE: errors.InternalServerError,
grpc.StatusCode.DATA_LOSS: errors.InternalServerError,
}


Expand Down
2 changes: 1 addition & 1 deletion src/momento/_momento_endpoint_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ def _getEndpointFromToken(auth_token):
return _Endpoints(claims[_CONTROL_ENDPOINT_CLAIM_ID],
claims[_CACHE_ENDPOINT_CLAIM_ID])
except (DecodeError, KeyError):
raise errors.InvalidInputError('Invalid Auth token.') from None
raise errors.InvalidArgumentError('Invalid Auth token.') from None
7 changes: 2 additions & 5 deletions src/momento/_scs_control_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from . import _momento_logger
from . import _scs_grpc_manager

from ._utilities._data_validation import _validate_cache_name


class _ScsControlClient:
"""Momento Internal."""
Expand Down Expand Up @@ -56,8 +58,3 @@ def _getStub(self):

def close(self):
self._grpc_manager.close()


def _validate_cache_name(cache_name):
if (cache_name is None):
raise errors.InvalidInputError('Cache Name cannot be None')
31 changes: 5 additions & 26 deletions src/momento/_scs_data_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from . import _momento_logger
from . import _scs_grpc_manager

from ._utilities._data_validation import _as_bytes, _validate_ttl, _make_metadata, _validate_cache_name


class _ScsDataClient:
"""Internal"""
Expand All @@ -22,8 +24,8 @@ def set(self, cache_name, key, value, ttl_seconds):
item_ttl_seconds = self._default_ttlSeconds if ttl_seconds is None else ttl_seconds
_validate_ttl(item_ttl_seconds)
set_request = cache_client_types.SetRequest()
set_request.cache_key = _asBytes(key, 'Unsupported type for key: ')
set_request.cache_body = _asBytes(value,
set_request.cache_key = _as_bytes(key, 'Unsupported type for key: ')
set_request.cache_body = _as_bytes(value,
'Unsupported type for value: ')
set_request.ttl_milliseconds = item_ttl_seconds * 1000
response = self._getStub().Set(set_request,
Expand All @@ -40,7 +42,7 @@ def get(self, cache_name, key):
try:
_momento_logger.debug(f'Issuing a get request with key {key}')
get_request = cache_client_types.GetRequest()
get_request.cache_key = _asBytes(key, 'Unsupported type for key: ')
get_request.cache_key = _as_bytes(key, 'Unsupported type for key: ')
response = self._getStub().Get(get_request,
metadata=_make_metadata(cache_name))
_momento_logger.debug(f'Received a get response for {key}')
Expand All @@ -54,26 +56,3 @@ def _getStub(self):

def close(self):
self._grpc_manager.close()


def _make_metadata(cache_name):
return (('cache', cache_name), )


def _validate_cache_name(cache_name):
if (cache_name is None):
raise errors.InvalidInputError('Cache Name cannot be None')


def _asBytes(data, errorMessage):
if (isinstance(data, str)):
return data.encode('utf-8')
if (isinstance(data, bytes)):
return data
raise errors.InvalidInputError(errorMessage + str(type(data)))


def _validate_ttl(ttl_seconds):
if (not isinstance(ttl_seconds, int) or ttl_seconds < 0):
raise errors.InvalidInputError(
'TTL Seconds must be a non-negative integer')
8 changes: 4 additions & 4 deletions src/momento/_utilities/_data_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ def _make_metadata(cache_name) -> Metadata:


def _validate_cache_name(cache_name):
if cache_name is None:
raise errors.InvalidInputError('Cache Name cannot be None')
if cache_name is None or not isinstance(cache_name, str):
raise errors.InvalidArgumentError('Cache name must be a non-empty string')


def _as_bytes(data, error_message):
if isinstance(data, str):
return data.encode('utf-8')
if isinstance(data, bytes):
return data
raise errors.InvalidInputError(error_message + str(type(data)))
raise errors.InvalidArgumentError(error_message + str(type(data)))


def _validate_ttl(ttl_seconds):
if not isinstance(ttl_seconds, int) or ttl_seconds < 0:
raise errors.InvalidInputError(
raise errors.InvalidArgumentError(
'TTL Seconds must be a non-negative integer')
38 changes: 18 additions & 20 deletions src/momento/aio/simple_cache_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ async def create_cache(self, cache_name) -> CreateCacheResponse:
CreateCacheResponse

Raises:
InvalidInputError: If cache name is None.
InvalidArgumentError: If provided cache_name None.
BadRequestError: If the cache name provided doesn't follow the naming conventions
ExistsError: If cache with the given name already exists.
AuthenticationError: If the provided Momento Auth Token is invalid.
ClientSdkError: For any SDK checks that fail.
CacheValueError: If provided cache_name is empty.
CacheExistsError: If cache with the given name already exists.
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
"""
return await self._control_client.create_cache(cache_name)

Expand All @@ -51,11 +51,11 @@ async def delete_cache(self, cache_name) -> DeleteCacheResponse:
DeleteCacheResponse

Raises:
CacheNotFoundError: If an attempt is made to delete a MomentoCache that doesn't exits.
InvalidInputError: If cache name is None.
InvalidArgumentError: If provided cache_name is None.
BadRequestError: If the cache name provided doesn't follow the naming conventions
NotFoundError: If an attempt is made to delete a MomentoCache that doesn't exits.
AuthenticationError: If the provided Momento Auth Token is invalid.
ClientSdkError: For any SDK checks that fail.
CacheValueError: If provided cache name is empty
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
"""
return await self._control_client.delete_cache(cache_name)

Expand All @@ -69,8 +69,7 @@ async def list_caches(self, next_token=None) -> ListCachesResponse:
ListCachesResponse

Raises:
Exception to notify either sdk, grpc, or operation error.
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
AuthenticationError: If the provided Momento Auth Token is invalid.
"""
return await self._control_client.list_caches(next_token)

Expand All @@ -87,10 +86,10 @@ async def set(self, cache_name, key, value, ttl_seconds=None) -> CacheSetRespons
CacheSetResponse

Raises:
InvalidInputError: If service validation fails for provided values.
ClientSdkError: If cache name is invalid type.
CacheNotFoundError: If an attempt is made to store an item in a cache that doesn't exist.
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
InvalidArgumentError: If validation fails for provided method arguments.
BadRequestError: If the provided inputs are rejected by server because they are invalid
NotFoundError: If the cache with the given name doesn't exist.
AuthenticationError: If the provided Momento Auth Token is invalid.
InternalServerError: If server encountered an unknown error while trying to store the item.
"""
return await self._data_client.set(cache_name, key, value, ttl_seconds)
Expand All @@ -106,10 +105,10 @@ async def get(self, cache_name, key) -> CacheGetResponse:
CacheGetResponse

Raises:
InvalidInputError: If service validation fails for provided values.
ClientSdkError: If cache name is invalid type.
CacheNotFoundError: If an attempt is made to retrieve an item in a cache that doesn't exist.
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
InvalidArgumentError: If validation fails for provided method arguments.
BadRequestError: If the provided inputs are rejected by server because they are invalid
NotFoundError: If the cache with the given name doesn't exist.
AuthenticationError: If the provided Momento Auth Token is invalid.
InternalServerError: If server encountered an unknown error while trying to retrieve the item.
"""
return await self._data_client.get(cache_name, key)
Expand All @@ -124,7 +123,6 @@ def init(auth_token, item_default_ttl_seconds) -> SimpleCacheClient:
Returns:
SimpleCacheClient
Raises:
InvalidInputError: If service validation fails for provided values
InternalServerError: If server encountered an unknown error.
IllegalArgumentError: If the provided auth token and/or item_default_ttl_seconds is invalid
"""
return SimpleCacheClient(auth_token, item_default_ttl_seconds)
32 changes: 28 additions & 4 deletions src/momento/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def __init__(self, message):
super().__init__(message)


class InvalidInputError(ClientSdkError):
class InvalidArgumentError(ClientSdkError):
"""Error raised when provided input values to the SDK are invalid

Some examples - missing required parameters, incorrect parameter
Expand All @@ -37,30 +37,54 @@ def __init__(self, message):
super().__init__(message)


class CacheNotFoundError(CacheServiceError):
class NotFoundError(CacheServiceError):
"""Error raised for operations performed on non-existent cache"""
def __init__(self, message):
super().__init__(message)


class CacheExistsError(CacheServiceError):
class AlreadyExistsError(CacheServiceError):
"""Error raised when attempting to create a cache with same name"""
def __init__(self, message):
super().__init__(message)


class CacheValueError(CacheServiceError):
class BadRequestError(CacheServiceError):
"""Error raised when service validation fails for provided values"""
def __init__(self, message):
super().__init__(message)


class PermissionError(CacheServiceError):
"""Error for insufficient permissions to perform an operation with Cache Service."""
def __init__(self, message):
super().__init__(message)


class AuthenticationError(CacheServiceError):
"""Error when authentication with Cache Service fails"""
def __init__(self, message):
super().__init__(message)


class CancelledError(CacheServiceError):
"""Error when an operation with Cache Service was cancelled"""
def __init__(self, message):
super().__init__(message)


class TimeoutError(CacheServiceError):
"""Error when an operation did not complete in time"""
def __init__(self, message):
super().__init__(message)


class LimitExceededError(CacheServiceError):
"""Error when calls are throttled due to request limit rate"""
def __init__(self, message):
super().__init__(message)


class InternalServerError(CacheServiceError):
"""Operation failed on the server with an unknown error"""
def __init__(self, message):
Expand Down
38 changes: 18 additions & 20 deletions src/momento/simple_cache_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ def create_cache(self, cache_name) -> CreateCacheResponse:
CreateCacheResponse

Raises:
InvalidInputError: If cache name is None.
InvalidArgumentError: If provided cache_name is None.
BadRequestError: If the cache name provided doesn't follow the naming conventions
AlreadyExistsError: If cache with the given name already exists.
AuthenticationError: If the provided Momento Auth Token is invalid.
ClientSdkError: For any SDK checks that fail.
CacheValueError: If provided cache_name is empty.
CacheExistsError: If cache with the given name already exists.
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
"""
return self._control_client.create_cache(cache_name)

Expand All @@ -49,11 +49,11 @@ def delete_cache(self, cache_name) -> DeleteCacheResponse:
DeleteCacheResponse

Raises:
CacheNotFoundError: If an attempt is made to delete a MomentoCache that doesn't exits.
InvalidInputError: If cache name is None.
InvalidArgumentError: If provided cache_name is None.
BadRequestError: If the cache name provided doesn't follow the naming conventions
NotFoundError: If an attempt is made to delete a MomentoCache that doesn't exits.
AuthenticationError: If the provided Momento Auth Token is invalid.
ClientSdkError: For any SDK checks that fail.
CacheValueError: If provided cache name is empty
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
"""
return self._control_client.delete_cache(cache_name)

Expand All @@ -67,8 +67,7 @@ def list_caches(self, next_token=None) -> ListCachesResponse:
ListCachesResponse

Raises:
Exception to notify either sdk, grpc, or operation error.
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
AuthenticationError: If the provided Momento Auth Token is invalid.
"""
return self._control_client.list_caches(next_token)

Expand All @@ -85,10 +84,10 @@ def set(self, cache_name, key, value, ttl_seconds=None) -> CacheSetResponse:
CacheSetResponse

Raises:
InvalidInputError: If service validation fails for provided values.
ClientSdkError: If cache name is invalid type.
CacheNotFoundError: If an attempt is made to store an item in a cache that doesn't exist.
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
InvalidArgumentError: If validation fails for the provided method arguments.
BadRequestError: If the provided inputs are rejected by server because they are invalid
NotFoundError: If the cache with the given name doesn't exist.
AuthenticationError: If the provided Momento Auth Token is invalid.
InternalServerError: If server encountered an unknown error while trying to store the item.
"""
return self._data_client.set(cache_name, key, value, ttl_seconds)
Expand All @@ -104,10 +103,10 @@ def get(self, cache_name, key) -> CacheGetResponse:
CacheGetResponse

Raises:
InvalidInputError: If service validation fails for provided values.
ClientSdkError: If cache name is invalid type.
CacheNotFoundError: If an attempt is made to retrieve an item in a cache that doesn't exist.
PermissionError: If the provided Momento Auth Token is invalid to perform the requested operation.
InvalidArgumentError: If validation fails for the provided method arguments.
BadRequestError: If the provided inputs are rejected by server because they are invalid
NotFoundError: If the cache with the given name doesn't exist.
AuthenticationError: If the provided Momento Auth Token is invalid.
InternalServerError: If server encountered an unknown error while trying to retrieve the item.
"""
return self._data_client.get(cache_name, key)
Expand All @@ -122,7 +121,6 @@ def init(auth_token, item_default_ttl_seconds) -> SimpleCacheClient:
Returns:
SimpleCacheClient
Raises:
InvalidInputError: If service validation fails for provided values
InternalServerError: If server encountered an unknown error.
IllegalArgumentError: If the provided auth token and/or item_default_ttl_seconds is invalid
"""
return SimpleCacheClient(auth_token, item_default_ttl_seconds)
Loading