"""Domain exceptions for repair workflows.""" class RepairError(Exception): """Base exception for repair operations.""" class RepairMinerNotFound(RepairError): """Raised when the requested miner does not exist.""" def __init__(self, miner_id: object): self.miner_id = miner_id super().__init__(f"Miner not found: {miner_id}") class RepairNotFound(RepairError): """Raised when the requested repair does not exist.""" def __init__(self, repair_id: object): self.repair_id = repair_id super().__init__(f"Repair not found: {repair_id}") class RepairConflict(RepairError): """Base exception for a conflicting repair state.""" class ActiveRepairConflict(RepairConflict): """Raised when a miner already has an active repair.""" def __init__(self, miner_id: object): self.miner_id = miner_id super().__init__(f"Miner already has an active repair: {miner_id}") class IncompatibleMinerLifecycle(RepairConflict): """Raised when the miner lifecycle cannot enter repair.""" def __init__(self, miner_id: object, lifecycle_status: object): self.miner_id = miner_id self.lifecycle_status = lifecycle_status super().__init__( "Miner lifecycle is incompatible with beginning repair: " f"{lifecycle_status}" ) class InconsistentRepairState(RepairConflict): """Raised when lifecycle state and repair records disagree.""" def __init__(self, miner_id: object): self.miner_id = miner_id super().__init__( "Miner is marked in repair but has no active repair record" ) class RepairActorRequired(RepairError): """Raised when an operational workflow lacks an authenticated actor.""" def __init__(self): super().__init__("An authenticated actor is required to begin repair") class RepairCompletionActorRequired(RepairError): """Raised when Return to Service lacks an authenticated actor.""" def __init__(self): super().__init__( "An authenticated actor is required to return a miner to service" ) class RepairNotActive(RepairConflict): """Raised when a repair is no longer active.""" def __init__(self, repair_id: object, repair_status: object): self.repair_id = repair_id self.repair_status = repair_status super().__init__( f"Repair is not active: {repair_id} ({repair_status})" ) class RepairMinerNotInRepair(RepairConflict): """Raised when a repair's miner has already left repair lifecycle.""" def __init__(self, miner_id: object, lifecycle_status: object): self.miner_id = miner_id self.lifecycle_status = lifecycle_status super().__init__( "Miner is not in repair lifecycle: " f"{miner_id} ({lifecycle_status})" ) class RepairActiveMismatch(RepairConflict): """Raised when the requested repair is not the miner's active repair.""" def __init__(self, repair_id: object, miner_id: object): self.repair_id = repair_id self.miner_id = miner_id super().__init__( f"Repair is not the active repair for miner: {repair_id}" ) class RepairPersistenceError(RepairError): """Raised when a required repair persistence operation fails.""" class ControlBoardReplacementActorRequired(RepairError): """Raised when a board replacement lacks an authenticated actor.""" def __init__(self): super().__init__("An authenticated actor is required to replace a control board") class ControlBoardReplacementConflict(RepairConflict): """Raised when current repair, component, or MAC state blocks replacement.""" class InvalidMacAddress(RepairError): """Raised when a replacement MAC is malformed or prohibited.""" def __init__(self, message: str = "New MAC address is invalid"): super().__init__(message) class MacOwnershipConflict(ControlBoardReplacementConflict): """Raised when a MAC belongs to another durable miner.""" def __init__(self, normalized_mac: str): self.normalized_mac = normalized_mac super().__init__( "MAC address has current or historical ownership on another miner" ) class RepairPartNotFound(RepairError): """Raised when a nested repair-part UUID does not exist for a repair.""" def __init__(self, repair_part_id: object): self.repair_part_id = repair_part_id super().__init__(f"Repair part not found: {repair_part_id}") class RepairPartComponentNotFound(RepairError): """Raised when a tracked component UUID does not exist.""" def __init__(self, component_id: object): self.component_id = component_id super().__init__(f"Component not found: {component_id}") class RepairPartValidationError(RepairError): """Raised when repair-part input violates a domain rule.""" class RepairPartActorRequired(RepairError): """Raised when a repair-part action lacks an authenticated actor.""" def __init__(self): super().__init__("An authenticated actor is required for repair-part actions") class RepairPartAlreadyVoided(RepairConflict): """Raised when an immutable repair-part entry was already voided.""" def __init__(self, repair_part_id: object): self.repair_part_id = repair_part_id super().__init__(f"Repair part is already voided: {repair_part_id}")