# Import Exception from the built-in module
from builtins import Exception
from typing import Any, Optional, Type
from jobshoplab.utils import get_logger
[docs]
class JobShopException(Exception):
[docs]
def __init__(self, message):
self.message = message
self.logger = get_logger(__name__, loglevel="error")
self.logger.error(self.message)
def __str__(self):
return self.message
[docs]
class StopIteration(JobShopException):
[docs]
def __init__(self, message):
self.message = message
super().__init__(self.message)
[docs]
class FileNotFound(JobShopException):
[docs]
def __init__(self, file):
self.message = f"File not found: {file}"
super().__init__(self.message)
[docs]
class NoJsspSpecified(JobShopException):
[docs]
def __init__(self):
self.message = f"No JSSP Instance specified"
super().__init__(self.message)
[docs]
class ValueNotSet(JobShopException):
[docs]
def __init__(self, key, value):
self.message = f"Value {key} not set: {value}"
super().__init__(self.message)
[docs]
class InvalidValue(JobShopException):
[docs]
def __init__(self, key, value, message=""):
self.message = f"Invalid value {key}: {value} {message}"
super().__init__(self.message)
[docs]
class InvalidKey(JobShopException):
[docs]
def __init__(self, key):
self.message = f"Invalid key: {key}"
super().__init__(self.message)
[docs]
class InvalidType(JobShopException):
[docs]
def __init__(self, key, value, expected_type):
self.message = f"Invalid type {key}: {value}, expected {expected_type}"
super().__init__(self.message)
[docs]
class NotImplementedError(JobShopException):
[docs]
def __init__(self):
self.message = f"Sorry not done yet"
super().__init__(self.message)
[docs]
class InvalidObservationSpace(JobShopException):
[docs]
def __init__(self, message):
self.message = f"Invalid observation space: {message}"
super().__init__(self.message)
[docs]
class InvalidActionSpace(JobShopException):
[docs]
def __init__(self, message):
self.message = f"Invalid action space: {message}"
super().__init__(self.message)
[docs]
class UnsuccessfulStateMachineResult(JobShopException):
[docs]
def __init__(self):
self.message = f"The state machine did not return a successful result. Can not continue."
super().__init__(self.message)
[docs]
class ActionOutOfActionSpace(JobShopException):
[docs]
def __init__(self, action, action_space):
self.message = f"Action {action} is out of action space {action_space}"
super().__init__(self.message)
[docs]
class EnvDone(JobShopException):
[docs]
def __init__(self):
self.message = f"Environment is done. Can not continue."
super().__init__(self.message)
[docs]
class DslSyntaxError(JobShopException):
[docs]
def __init__(self, message, line):
self.message = f"DSL Syntax Error: {message} at line {line}"
super().__init__(self.message)
[docs]
class MissingSpecificationError(JobShopException):
[docs]
def __init__(self, specification_name):
self.message = f"Missing required specification: {specification_name}"
super().__init__(self.message)
[docs]
class InvalidTimeSpecification(JobShopException):
[docs]
def __init__(self, message):
self.message = f"Invalid time specification: {message}"
super().__init__(self.message)
[docs]
class UnknownLocationNameError(JobShopException):
[docs]
def __init__(self, name):
self.message = f"Unknown location name: {name}"
super().__init__(self.message)
[docs]
class InvalidDurationError(JobShopException):
[docs]
def __init__(self, value, expected_type="integer"):
self.message = f"Duration must be an {expected_type}, got {type(value).__name__}"
super().__init__(self.message)
[docs]
class InvalidDistributionError(JobShopException):
[docs]
def __init__(self, message):
self.message = f"Invalid distribution specification: {message}"
super().__init__(self.message)
[docs]
class UnknownDistributionTypeError(JobShopException):
[docs]
def __init__(self, dist_type):
self.message = f"Unknown distribution function: {dist_type}"
super().__init__(self.message)
[docs]
class InvalidTimeBehaviorError(JobShopException):
[docs]
def __init__(self, behavior):
self.message = f"Unknown time behavior: {behavior}"
super().__init__(self.message)
[docs]
class InvalidSetupTimesError(JobShopException):
[docs]
def __init__(self, machine_id):
self.message = f"No setup times found for machine {machine_id}"
super().__init__(self.message)
[docs]
class InvalidTransportConfig(JobShopException):
[docs]
def __init__(self, message):
self.message = f"Invalid transport configuration: {message}"
super().__init__(self.message)
[docs]
class ComponentAssociationError(JobShopException):
[docs]
def __init__(self, component_id, component_type):
self.message = (
f"{component_type} with id={component_id} cannot be associated with a machine"
)
super().__init__(self.message)
[docs]
class MissingComponentError(JobShopException):
[docs]
def __init__(self, component_id, component_type):
self.message = f"Missing {component_type} component with id={component_id}"
super().__init__(self.message)
[docs]
class InvalidOutageTypeError(JobShopException):
[docs]
def __init__(self, outage_type):
self.message = f"Unknown outage type: {outage_type}"
super().__init__(self.message)
[docs]
class BufferFullError(JobShopException):
[docs]
def __init__(self, buffer_id):
self.message = f"Buffer {buffer_id} is full, cannot add more items"
super().__init__(self.message)
[docs]
class JobNotInBufferError(JobShopException):
[docs]
def __init__(self, job_id, buffer_id):
self.message = f"Job {job_id} not found in buffer {buffer_id}"
super().__init__(self.message)
[docs]
class InvalidDispatchRuleError(JobShopException):
[docs]
def __init__(self, mode, allowed_modes):
self.message = f"Invalid dispatch rule mode: {mode}. Allowed modes: {allowed_modes}"
super().__init__(self.message)
[docs]
class OperationMachineMatchError(JobShopException):
[docs]
def __init__(self, operation_id, expected_machine, actual_machine):
self.message = f"Operation {operation_id} is in prebuffer of machine {expected_machine} but is assigned to machine {actual_machine}"
super().__init__(self.message)
[docs]
class MissingJobIdError(JobShopException):
[docs]
def __init__(self, transition_type=None):
transition_info = f" in {transition_type} transition" if transition_type else ""
self.message = f"No job_id{transition_info}"
super().__init__(self.message)
[docs]
class TransportJobError(JobShopException):
[docs]
def __init__(self, transport_id, transport_job=None):
if transport_job is None:
self.message = f"Transport {transport_id} has no transport_job assigned"
else:
self.message = f"Invalid transport_job for transport {transport_id}: {transport_job}"
super().__init__(self.message)
[docs]
class MissingProcessingOperationError(JobShopException):
[docs]
def __init__(self, job_id=None):
job_info = f" for job {job_id}" if job_id else ""
self.message = f"No processing operation found{job_info} -> AGV cannot wait for pickup!"
super().__init__(self.message)
[docs]
class TransportConfigError(JobShopException):
[docs]
def __init__(self, config_field, value=None):
if value is None:
self.message = f"Invalid transport configuration: {config_field}"
else:
self.message = f"Invalid transport configuration: {config_field}={value}"
super().__init__(self.message)
[docs]
class TravelTimeError(JobShopException):
[docs]
def __init__(self, source, destination):
self.message = f"No travel time found between {source} and {destination}"
super().__init__(self.message)
[docs]
class InstanceSchemaError(JobShopException):
[docs]
def __init__(self, message, field=None):
if field:
self.message = f"Instance schema error in field '{field}': {message}"
else:
self.message = f"Instance schema error: {message}"
super().__init__(self.message)
[docs]
class MissingRequiredFieldError(InstanceSchemaError):
[docs]
def __init__(self, field_name, parent_field=None):
self.field = field_name
if parent_field:
self.message = f"Missing required field '{field_name}' in '{parent_field}'"
else:
self.message = f"Missing required field '{field_name}'"
super().__init__(self.message, field_name)
[docs]
class InvalidFieldValueError(InstanceSchemaError):
[docs]
def __init__(self, field_name, value, expected_format=None):
self.field = field_name
if expected_format:
self.message = f"Invalid value '{value}' for field '{field_name}'. Expected format: {expected_format}"
else:
self.message = f"Invalid value '{value}' for field '{field_name}'"
super().__init__(self.message, field_name)
[docs]
class JobSpecificationSyntaxError(InstanceSchemaError):
[docs]
def __init__(self, line_number, line_content, details=None):
self.line_number = line_number
self.line_content = line_content
message = f"Invalid job specification syntax at line {line_number}: '{line_content}'"
if details:
message += f" - {details}"
super().__init__(message, "instance.specification")
[docs]
class KeyError(JobShopException):
[docs]
def __init__(self, key):
self.message = f"Key not found: {key}"
super().__init__(self.message)
[docs]
class IndexError(JobShopException):
[docs]
def __init__(self, index, sequence_length=None):
if sequence_length is not None:
self.message = f"Index {index} out of bounds for sequence of length {sequence_length}"
else:
self.message = f"Index {index} out of range"
super().__init__(self.message)
[docs]
class ValueError(JobShopException):
[docs]
def __init__(self, value, message=""):
self.message = f"Invalid value: {value} {message}"
super().__init__(self.message)
[docs]
class AttributeError(JobShopException):
[docs]
def __init__(self, obj, attr):
self.message = f"'{type(obj).__name__}' object has no attribute '{attr}'"
super().__init__(self.message)
[docs]
class ImportError(JobShopException):
[docs]
def __init__(self, module):
self.message = f"Failed to import module: {module}"
super().__init__(self.message)
[docs]
class ConfigurationError(JobShopException):
[docs]
def __init__(self, config_name, value=None, details=None):
if value is not None:
self.message = f"Invalid {config_name} configuration: {value}"
else:
self.message = f"Missing or invalid {config_name} configuration"
if details:
self.message += f" - {details}"
super().__init__(self.message)
[docs]
class InvalidTimeTypeError(JobShopException):
[docs]
def __init__(self, actual_type, expected_types=None):
type_info = f"Expected {expected_types}" if expected_types else ""
self.message = f"Invalid time type: {actual_type}. {type_info}"
super().__init__(self.message)
[docs]
class InvalidSetupTimeTypeError(JobShopException):
[docs]
def __init__(self, actual_type, expected_types=None):
type_info = f"Expected {expected_types}" if expected_types else ""
self.message = f"Invalid setup time type: {actual_type}. {type_info}"
super().__init__(self.message)