class StorageError(Exception):
    """
    Exception raised for storage-related errors.

    This exception is raised when there are issues with storage operations
    such as file I/O, database connections, cloud storage access, or other
    storage-related failures in the ML pipeline.

    Attributes:
        message (str): Explanation of the error
        error_code (str, optional): Specific error code for categorization
        storage_type (str, optional): Type of storage that caused the error
        details (dict, optional): Additional error details
    """

    def __init__(self, message, error_code=None, storage_type=None, details=None):
        """
        Initialize StorageError.

        Args:
            message (str): Human-readable error message
            error_code (str, optional): Specific error code
            storage_type (str, optional): Type of storage (e.g., 'local', 's3', 'gcs')
            details (dict, optional): Additional context about the error
        """
        super().__init__(message)
        self.message = message
        self.error_code = error_code
        self.storage_type = storage_type
        self.details = details or {}

    def __str__(self):
        """Return a formatted string representation of the error."""
        parts = [self.message]

        if self.storage_type:
            parts.append(f"Storage type: {self.storage_type}")

        if self.error_code:
            parts.append(f"Error code: {self.error_code}")

        return " | ".join(parts)

    def __repr__(self):
        """Return a detailed representation of the error."""
        return (
            f"StorageError(message={self.message!r}, "
            f"error_code={self.error_code!r}, "
            f"storage_type={self.storage_type!r}, "
            f"details={self.details!r})"
        )


class DatasetError(Exception):
    """
    Exception raised for dataset-related errors.

    Attributes:
        message (str): Explanation of the error
        error_code (str, optional): Specific error code for categorization
        task_type (str, optional): Task type which configured
        file_format (str, optional): File format of the dataset
        details (dict, optional): Additional error details
    """

    def __init__(self, message, error_code=None, task_type=None, file_format=None, details=None):
        """
        Initialize DatasetError.

        Args:
            message (str): Human-readable error message
            error_code (str, optional): Specific error code
            task_type (str, optional): Task Type (e.g., 'local', 's3', 'gcs')
            file_format (str, optional): Dataset file format
            details (dict, optional): Additional context about the error
        """
        super().__init__(message)
        self.message = message
        self.error_code = error_code
        self.task_type = task_type
        self.file_format = file_format
        self.details = details or {}

    def __str__(self):
        """Return a formatted string representation of the error."""
        parts = [self.message]

        if self.task_type:
            parts.append(f"Task type: {self.task_type}")

        if self.file_format:
            parts.append(f"File format: {self.file_format}")

        if self.error_code:
            parts.append(f"Error code: {self.error_code}")

        return " | ".join(parts)

    def __repr__(self):
        """Return a detailed representation of the error."""
        return (
            f"StorageError(message={self.message!r}, "
            f"error_code={self.error_code!r}, "
            f"task_type={self.task_type!r}, "
            f"file_format={self.file_format!r}, "
            f"details={self.details!r})"
        )

