feat: consistent error handling
This commit is contained in:
@@ -10,7 +10,11 @@ class Auth:
|
|||||||
self.client = None
|
self.client = None
|
||||||
|
|
||||||
def login(self) -> Client:
|
def login(self) -> Client:
|
||||||
|
try:
|
||||||
config_data = self.config.load()
|
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")
|
handle = config_data.get("handle")
|
||||||
password = config_data.get("password")
|
password = config_data.get("password")
|
||||||
@@ -19,7 +23,11 @@ class Auth:
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
"handle and password must be set in configuration")
|
"handle and password must be set in configuration")
|
||||||
|
|
||||||
|
try:
|
||||||
self.client = Client()
|
self.client = Client()
|
||||||
self.client.login(handle, password)
|
self.client.login(handle, password)
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(
|
||||||
|
f"Failed to authenticate: {e}") from e
|
||||||
|
|
||||||
return self.client
|
return self.client
|
||||||
|
|||||||
@@ -63,12 +63,22 @@ def _create_operation_handler(
|
|||||||
) -> CommandHandler:
|
) -> CommandHandler:
|
||||||
def handler(skip_confirmation: bool = False):
|
def handler(skip_confirmation: bool = False):
|
||||||
require_confirmation(confirmation_message, skip_confirmation)
|
require_confirmation(confirmation_message, skip_confirmation)
|
||||||
|
try:
|
||||||
Operation(
|
Operation(
|
||||||
operation_name,
|
operation_name,
|
||||||
strategy_type=strategy_type,
|
strategy_type=strategy_type,
|
||||||
collection=collection,
|
collection=collection,
|
||||||
filter_fn=filter_fn
|
filter_fn=filter_fn
|
||||||
).run()
|
).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
|
return handler
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -51,8 +51,12 @@ class Configuration:
|
|||||||
"verbose": verbose
|
"verbose": verbose
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
with open(self.config_file, "w") as f:
|
with open(self.config_file, "w") as f:
|
||||||
yaml.dump(config_data, f, default_flow_style=False)
|
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}")
|
logger.info(f"Configuration saved to {self.config_file}")
|
||||||
|
|
||||||
@@ -60,5 +64,15 @@ class Configuration:
|
|||||||
if not self.exists():
|
if not self.exists():
|
||||||
raise FileNotFoundError(
|
raise FileNotFoundError(
|
||||||
f"Configuration file not found: {self.config_file}")
|
f"Configuration file not found: {self.config_file}")
|
||||||
|
try:
|
||||||
with open(self.config_file, "r") as f:
|
with open(self.config_file, "r") as f:
|
||||||
return yaml.safe_load(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
|
||||||
|
|||||||
@@ -12,10 +12,20 @@ from .logger import get_logger, ProgressTracker
|
|||||||
class OperationContext:
|
class OperationContext:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.logger = get_logger()
|
self.logger = get_logger()
|
||||||
|
try:
|
||||||
self.auth = Auth()
|
self.auth = Auth()
|
||||||
self.client = self.auth.login()
|
self.client = self.auth.login()
|
||||||
self.config = Configuration()
|
self.config = Configuration()
|
||||||
self.config_data = self.config.load()
|
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.batch_size = self.config_data.get("batch_size", 10)
|
||||||
self.delay = self.config_data.get("delay", 1)
|
self.delay = self.config_data.get("delay", 1)
|
||||||
self.did = self.client.me.did
|
self.did = self.client.me.did
|
||||||
@@ -138,8 +148,13 @@ class Operation:
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
batch_num += 1
|
batch_num += 1
|
||||||
|
try:
|
||||||
response = self.strategy.fetch(context, cursor)
|
response = self.strategy.fetch(context, cursor)
|
||||||
items = self.strategy.extract_items(response)
|
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:
|
if not items:
|
||||||
break
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user