Skip to content
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

Replace SyftError return values with rising PySyftExceptions #8120

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4a46d83
ADD exceptions submodule
IonesioJunior Sep 7, 2023
0fbcd7b
Start submodule for Exception Handling
IonesioJunior Sep 7, 2023
318641c
Update abstract.py
IonesioJunior Sep 7, 2023
45f5723
Merge branch 'dev' into init_exception_handling
onlyoneuche Sep 7, 2023
07a34e5
Merge branch 'dev' of https://github.com/OpenMined/PySyft into dev
IonesioJunior Sep 13, 2023
eabaabc
Exception Handling refactor
IonesioJunior Sep 13, 2023
8284693
Merge remote-tracking branch 'origin/dev' into init_exception_handling
IonesioJunior Sep 13, 2023
f9a208a
Exception Handling refactor
IonesioJunior Sep 13, 2023
3db5a98
Merge branch 'dev' into init_exception_handling
IonesioJunior Sep 13, 2023
6f2afcb
Fix merge conflicts
IonesioJunior Sep 13, 2023
99d2e61
Merge branch 'dev' into init_exception_handling
IonesioJunior Sep 19, 2023
4111f2e
Merge branch 'dev' into init_exception_handling
IonesioJunior Sep 21, 2023
cfe5540
Merge branch 'dev' into init_exception_handling
IonesioJunior Sep 21, 2023
f6c0382
Merge branch 'dev' into init_exception_handling
tcp Sep 21, 2023
e988152
fix: remove mutable object as argument in exception init
tcp Sep 25, 2023
33d05de
Merge branch 'dev' into init_exception_handling
tcp Sep 25, 2023
50aa59d
Merge branch 'dev' into init_exception_handling
tcp Sep 26, 2023
6821604
Replace SyftErrors with PySyftExceptions
jcardonnet Sep 28, 2023
99277a7
Merge branch 'dev' into jcardonnet/init_exception_handling
madhavajay Oct 2, 2023
309817d
Merge branch 'dev' into jcardonnet/init_exception_handling
madhavajay Oct 2, 2023
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
Empty file.
27 changes: 27 additions & 0 deletions packages/syft/src/syft/exceptions/exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# stdlib
from typing import List
from typing import Optional

# relative
from ..service.context import NodeServiceContext
from ..service.response import SyftError
from ..service.user.user_roles import ServiceRole


class PySyftException(Exception):
"""Base class for all PySyft exceptions."""

def __init__(self, message: str, roles: Optional[List[ServiceRole]] = None):
super().__init__(message)
self.message = message
self.roles = roles if roles else [ServiceRole.ADMIN]

def raise_with_context(self, context: NodeServiceContext):
self.context = context
return self

def handle(self) -> SyftError:
if self.context and self.context.role in self.roles:
return SyftError(message=self.message)
else:
return SyftError(message="Access denied to exception message.")
35 changes: 35 additions & 0 deletions packages/syft/src/syft/exceptions/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# stdlib

# relative
from ..service.user.user_roles import ServiceRole
from .exception import PySyftException

UserAlreadyExistsException = PySyftException(
message="User already exists", roles=[ServiceRole.ADMIN]
)

UserNotFoundException = PySyftException(
message="User not found", roles=[ServiceRole.ADMIN]
)
AdminVerifyKeyException = PySyftException(
message="Failed to get admin verify_key", roles=[ServiceRole.ADMIN]
)
RoleNotFoundException = PySyftException(
message="Role not found", roles=[ServiceRole.ADMIN]
)


def NoUserWithVerifyKeyException(verify_key: str) -> PySyftException:
return PySyftException(
message=f"No User with verify_key: {verify_key}", roles=[ServiceRole.ADMIN]
)


def NoUserWithEmailException(email: str) -> PySyftException:
return PySyftException(
message=f"No User with email: {email}", roles=[ServiceRole.ADMIN]
)


def StashRetrievalException(message: str) -> PySyftException:
return PySyftException(message=message, roles=[ServiceRole.ADMIN])
3 changes: 3 additions & 0 deletions packages/syft/src/syft/node/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from ..client.api import SyftAPICall
from ..client.api import SyftAPIData
from ..client.api import debox_signed_syftapicall_response
from ..exceptions.exception import PySyftException
from ..external import OBLV
from ..serde.deserialize import _deserialize
from ..serde.serialize import _serialize
Expand Down Expand Up @@ -806,6 +807,8 @@ def handle_api_call_with_unsigned_result(
method = self.get_service_method(_private_api_path)
try:
result = method(context, *api_call.args, **api_call.kwargs)
except PySyftException as e:
return e.handle()
except Exception:
result = SyftError(
message=f"Exception calling {api_call.path}. {traceback.format_exc()}"
Expand Down
63 changes: 37 additions & 26 deletions packages/syft/src/syft/service/user/user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

# relative
from ...abstract_node import NodeType
from ...exceptions.user import AdminVerifyKeyException
from ...exceptions.user import NoUserWithEmailException
from ...exceptions.user import NoUserWithVerifyKeyException
from ...exceptions.user import StashRetrievalException
from ...exceptions.user import UserAlreadyExistsException
from ...node.credentials import SyftSigningKey
from ...node.credentials import SyftVerifyKey
from ...node.credentials import UserLoginCredentials
Expand Down Expand Up @@ -235,9 +240,7 @@ def update(
email=user_update.email
)
if user_with_email_exists:
return SyftError(
message=f"A user with the email {user_update.email} already exists."
)
raise UserAlreadyExistsException.raise_with_context(context=context)

if result.is_err():
error_msg = (
Expand Down Expand Up @@ -389,17 +392,6 @@ def exchange_credentials(
f"{context.login_credentials.email} with error: {result.err()}"
)

def admin_verify_key(self) -> Union[SyftVerifyKey, SyftError]:
try:
result = self.stash.admin_verify_key()
if result.is_ok():
return result.ok()
else:
return SyftError(message="failed to get admin verify_key")

except Exception as e:
return SyftError(message=str(e))

def register(
self, context: NodeServiceContext, new_user: UserCreate
) -> Union[Tuple[SyftSuccess, UserPrivateKey], SyftError]:
Expand Down Expand Up @@ -449,25 +441,44 @@ def register(
msg = SyftSuccess(message=success_message)
return (msg, user.to(UserPrivateKey))

def user_verify_key(self, email: str) -> Union[SyftVerifyKey, SyftError]:
def admin_verify_key(self) -> SyftVerifyKey:
try:
result = self.stash.admin_verify_key()
except Exception as e:
raise StashRetrievalException(message=repr(e)) from e

if result.is_ok() and result.ok() is not None:
return result.ok()
else:
raise AdminVerifyKeyException

def user_verify_key(self, email: str) -> SyftVerifyKey:
# we are bypassing permissions here, so dont use to return a result directly to the user
credentials = self.admin_verify_key()
result = self.stash.get_by_email(credentials=credentials, email=email)
if result.ok() is not None:
try:
result = self.stash.get_by_email(credentials=credentials, email=email)
except Exception as e:
raise StashRetrievalException(message=repr(e)) from e

if result.is_ok() and result.ok() is not None:
return result.ok().verify_key
return SyftError(message=f"No user with email: {email}")
else:
raise NoUserWithEmailException(email)

def get_by_verify_key(
self, verify_key: SyftVerifyKey
) -> Union[UserView, SyftError]:
def get_by_verify_key(self, verify_key: SyftVerifyKey) -> User:
# we are bypassing permissions here, so dont use to return a result directly to the user
credentials = self.admin_verify_key()
result = self.stash.get_by_verify_key(
credentials=credentials, verify_key=verify_key
)
if result.is_ok():
try:
result = self.stash.get_by_verify_key(
credentials=credentials, verify_key=verify_key
)
except Exception as e:
raise StashRetrievalException(message=repr(e)) from e

if result.is_ok() and result.ok() is not None:
return result.ok()
return SyftError(message=f"No User with verify_key: {verify_key}")
else:
raise NoUserWithVerifyKeyException(verify_key.verify)


TYPE_TO_SERVICE[User] = UserService
Expand Down