diff --git a/skywipe/auth.py b/skywipe/auth.py index e692bf1..d6addf3 100644 --- a/skywipe/auth.py +++ b/skywipe/auth.py @@ -10,7 +10,11 @@ class Auth: self.client = None def login(self) -> Client: - config_data = self.config.load() + try: + config_data = self.config.load() + except FileNotFoundError as e: + raise ValueError( + "Configuration file not found. Run 'skywipe configure' first.") from e handle = config_data.get("handle") password = config_data.get("password") @@ -19,7 +23,11 @@ class Auth: raise ValueError( "handle and password must be set in configuration") - self.client = Client() - self.client.login(handle, password) + try: + self.client = Client() + self.client.login(handle, password) + except Exception as e: + raise ValueError( + f"Failed to authenticate: {e}") from e return self.client diff --git a/skywipe/commands.py b/skywipe/commands.py index 937ee28..13a647c 100644 --- a/skywipe/commands.py +++ b/skywipe/commands.py @@ -63,12 +63,22 @@ def _create_operation_handler( ) -> CommandHandler: def handler(skip_confirmation: bool = False): require_confirmation(confirmation_message, skip_confirmation) - Operation( - operation_name, - strategy_type=strategy_type, - collection=collection, - filter_fn=filter_fn - ).run() + try: + Operation( + operation_name, + strategy_type=strategy_type, + collection=collection, + filter_fn=filter_fn + ).run() + except ValueError as e: + logger = get_logger() + logger.error(f"{e}") + raise + except Exception as e: + logger = get_logger() + logger.error( + f"Unexpected error during operation: {e}", exc_info=True) + raise return handler diff --git a/skywipe/configure.py b/skywipe/configure.py index cb69bc7..df2cdce 100644 --- a/skywipe/configure.py +++ b/skywipe/configure.py @@ -51,8 +51,12 @@ class Configuration: "verbose": verbose } - with open(self.config_file, "w") as f: - yaml.dump(config_data, f, default_flow_style=False) + try: + with open(self.config_file, "w") as f: + yaml.dump(config_data, f, default_flow_style=False) + except (IOError, OSError) as e: + logger.error(f"Failed to save configuration: {e}") + return logger.info(f"Configuration saved to {self.config_file}") @@ -60,5 +64,15 @@ class Configuration: if not self.exists(): raise FileNotFoundError( f"Configuration file not found: {self.config_file}") - with open(self.config_file, "r") as f: - return yaml.safe_load(f) + try: + with open(self.config_file, "r") as f: + config_data = yaml.safe_load(f) + if config_data is None: + raise ValueError("Configuration file is empty or invalid") + return config_data + except (IOError, OSError) as e: + raise ValueError( + f"Failed to read configuration file: {e}") from e + except yaml.YAMLError as e: + raise ValueError( + f"Invalid YAML in configuration file: {e}") from e diff --git a/skywipe/operations.py b/skywipe/operations.py index 113b589..601c516 100644 --- a/skywipe/operations.py +++ b/skywipe/operations.py @@ -12,10 +12,20 @@ from .logger import get_logger, ProgressTracker class OperationContext: def __init__(self): self.logger = get_logger() - self.auth = Auth() - self.client = self.auth.login() - self.config = Configuration() - self.config_data = self.config.load() + try: + self.auth = Auth() + self.client = self.auth.login() + self.config = Configuration() + self.config_data = self.config.load() + except (ValueError, FileNotFoundError) as e: + self.logger.error(f"Configuration error: {e}") + raise + except Exception as e: + self.logger.error( + f"Unexpected error during initialization: {e}", exc_info=True) + raise ValueError( + f"Failed to initialize operation context: {e}") from e + self.batch_size = self.config_data.get("batch_size", 10) self.delay = self.config_data.get("delay", 1) self.did = self.client.me.did @@ -138,8 +148,13 @@ class Operation: while True: batch_num += 1 - response = self.strategy.fetch(context, cursor) - items = self.strategy.extract_items(response) + try: + response = self.strategy.fetch(context, cursor) + items = self.strategy.extract_items(response) + except Exception as e: + context.logger.error( + f"Error fetching items for batch {batch_num}: {e}", exc_info=True) + break if not items: break