Skip to content

Improved exception handling #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Nov 5, 2024
4 changes: 3 additions & 1 deletion cs3client/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"""

import logging
from typing import Optional

import cs3.app.registry.v1beta1.registry_api_pb2 as cs3arreg
import cs3.app.registry.v1beta1.resources_pb2 as cs3arres
import cs3.gateway.v1beta1.gateway_api_pb2 as cs3gw
Expand Down Expand Up @@ -44,7 +46,7 @@ def __init__(
self._config: Config = config

def open_in_app(
self, auth_token: tuple, resource: Resource, view_mode: str = None, app: str = None
self, auth_token: tuple, resource: Resource, view_mode: Optional[str] = None, app: Optional[str] = None
) -> cs3apr.OpenInAppURL:
"""
Open a file in an app, given the resource, view mode (VIEW_MODE_VIEW_ONLY, VIEW_MODE_READ_ONLY,
Expand Down
2 changes: 1 addition & 1 deletion cs3client/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from cs3.rpc.v1beta1.code_pb2 import CODE_OK

from .cs3client import CS3Client
from .exceptions.exceptions import AuthenticationException, SecretNotSetException
from .exceptions import AuthenticationException, SecretNotSetException
from .config import Config


Expand Down
5 changes: 3 additions & 2 deletions cs3client/checkpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
Last updated: 30/08/2024
"""

from typing import Generator
from typing import Generator, Optional
import logging

import cs3.storage.provider.v1beta1.resources_pb2 as cs3spr
import cs3.storage.provider.v1beta1.provider_api_pb2 as cs3spp
from cs3.gateway.v1beta1.gateway_api_pb2_grpc import GatewayAPIStub
Expand Down Expand Up @@ -65,7 +66,7 @@ def list_file_versions(
return res.versions

def restore_file_version(
self, auth_token: tuple, resource: Resource, version_key: str, lock_id: str = None
self, auth_token: tuple, resource: Resource, version_key: str, lock_id: Optional[str] = None
) -> None:
"""
Restore a file to a previous version.
Expand Down
84 changes: 84 additions & 0 deletions cs3client/exceptions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""
exceptions

Custom exception classes for the CS3 client.
Where applicable, the default values correspond to the Linux standard error strings.

Authors: Rasmus Welander, Diogo Castro, Giuseppe Lo Presti.
Emails: [email protected], [email protected], [email protected]
Last updated: 01/08/2024
"""


class AuthenticationException(Exception):
"""
Standard error thrown when attempting an operation without the required access rights
"""

def __init__(self, message: str = "Operation not permitted"):
super().__init__(message)


class PermissionDeniedException(IOError):
"""
Standard permission denied message
"""

def __init__(self, message: str = "Permission denied"):
super().__init__(message)


class NotFoundException(IOError):
"""
Standard file missing message
"""

def __init__(self, message: str = "No such file or directory"):
super().__init__(message)


class SecretNotSetException(Exception):
"""
Standard file missing message
"""

def __init__(self, message: str = "Secret was not set, unable to authenticate"):
super().__init__(message)


class FileLockedException(IOError):
"""
Standard error thrown when attempting to overwrite a file/xattr with a mistmatched lock,
or when a lock operation cannot be performed because of failed preconditions
"""

def __init__(self, message: str = "Lock mismatch"):
super().__init__(message)


class AlreadyExistsException(IOError):
"""
Standard error thrown when attempting to create a resource that already exists
"""

def __init__(self, message: str = "File exists"):
super().__init__(message)


class UnimplementedException(Exception):
"""
Standard error thrown when attempting to use a feature that is not implemented
"""

def __init__(self, message: str = "Not implemented"):
super().__init__(message)


class UnknownException(Exception):
"""
Standard exception to be thrown when we get an error that is unknown, e.g. not defined in the cs3api
"""

def __init__(self, message: str = ""):
super().__init__(message)

73 changes: 0 additions & 73 deletions cs3client/exceptions/exceptions.py

This file was deleted.

26 changes: 13 additions & 13 deletions cs3client/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
import logging
import http
import requests
from typing import Union
from typing import Generator
from typing import Union, Optional, Generator
import cs3.storage.provider.v1beta1.resources_pb2 as cs3spr
import cs3.storage.provider.v1beta1.provider_api_pb2 as cs3sp
from cs3.gateway.v1beta1.gateway_api_pb2_grpc import GatewayAPIStub
Expand All @@ -20,7 +19,7 @@


from .config import Config
from .exceptions.exceptions import AuthenticationException, FileLockedException
from .exceptions import AuthenticationException, FileLockedException
from .cs3resource import Resource
from .statuscodehandler import StatusCodeHandler

Expand Down Expand Up @@ -71,7 +70,7 @@ def stat(self, auth_token: tuple, resource: Resource) -> cs3spr.ResourceInfo:
)
return res.info

def set_xattr(self, auth_token: tuple, resource: Resource, key: str, value: str, lock_id: str = None) -> None:
def set_xattr(self, auth_token: tuple, resource: Resource, key: str, value: str, lock_id: Optional[str] = None) -> None:
"""
Set the extended attribute <key> to <value> for a resource.

Expand All @@ -94,7 +93,7 @@ def set_xattr(self, auth_token: tuple, resource: Resource, key: str, value: str,
self._status_code_handler.handle_errors(res.status, "set extended attribute", resource.get_file_ref_str())
self._log.debug(f'msg="Invoked setxattr" trace="{res.status.trace}"')

def remove_xattr(self, auth_token: tuple, resource: Resource, key: str, lock_id: str = None) -> None:
def remove_xattr(self, auth_token: tuple, resource: Resource, key: str, lock_id: Optional[str] = None) -> None:
"""
Remove the extended attribute <key>.

Expand All @@ -113,7 +112,7 @@ def remove_xattr(self, auth_token: tuple, resource: Resource, key: str, lock_id:
self._log.debug(f'msg="Invoked UnsetArbitraryMetaData" trace="{res.status.trace}"')

def rename_file(
self, auth_token: tuple, resource: Resource, newresource: Resource, lock_id: str = None
self, auth_token: tuple, resource: Resource, newresource: Resource, lock_id: Optional[str] = None
) -> None:
"""
Rename/move resource to new resource.
Expand All @@ -133,7 +132,7 @@ def rename_file(
self._status_code_handler.handle_errors(res.status, "rename file", resource.get_file_ref_str())
self._log.debug(f'msg="Invoked Move" trace="{res.status.trace}"')

def remove_file(self, auth_token: tuple, resource: Resource, lock_id: str = None) -> None:
def remove_file(self, auth_token: tuple, resource: Resource, lock_id: Optional[str] = None) -> None:
"""
Remove a resource.

Expand Down Expand Up @@ -171,7 +170,8 @@ def touch_file(self, auth_token: tuple, resource: Resource) -> None:

def write_file(
self, auth_token: tuple, resource: Resource, content: Union[str, bytes], size: int,
lock_md: tuple = ('', ''), disable_versioning: bool = False
app_name: Optional[str] = None, lock_id: Optional[str] = None,
disable_versioning: Optional[bool] = False
) -> None:
"""
Write a file using the given userid as access token. The entire content is written
Expand All @@ -183,15 +183,15 @@ def write_file(
:param resource: Resource to write content to
:param content: content to write
:param size: size of content (optional)
:param lock_md: tuple (<app_name>, <lock_id>)
:param disable_versioning: bool to disable versioning on EOS
:param app_name: application name (optional)
:param lock_id: lock id (optional)
:param disable_versioning: bool to disable versioning on EOS (optional)
:return: None (Success)
:raises: FileLockedException (File is locked),
:raises: AuthenticationException (Authentication failed)
:raises: UnknownException (Unknown error)

"""
app_name, lock_id = lock_md
tstart = time.time()
# prepare endpoint
if size == -1:
Expand Down Expand Up @@ -229,7 +229,7 @@ def write_file(
"X-Reva-Transfer": protocol.token,
**dict([auth_token]),
"X-Lock-Id": lock_id,
"X-Lock_Holder": app_name,
"X-Lock-Holder": app_name,
}
if disable_versioning:
headers.update({"X-Disable-Versioning": "true"})
Expand Down Expand Up @@ -273,7 +273,7 @@ def write_file(
f'elapsedTimems="{(tend - tstart) * 1000:.1f}"'
)

def read_file(self, auth_token: tuple, resource: Resource, lock_id: str = None) -> Generator[bytes, None, None]:
def read_file(self, auth_token: tuple, resource: Resource, lock_id: Optional[str] = None) -> Generator[bytes, None, None]:
"""
Read a file. Note that the function is a generator, managed by the app server.

Expand Down
Loading
Loading