Source code for voxelops.exceptions

"""Custom exceptions for yalab-procedures.

This module defines a hierarchy of exceptions for consistent error handling
across all procedures in the yalab-procedures package.
"""

from typing import Optional


[docs] class YALabProcedureError(Exception): """Base exception for all yalab-procedures errors. All custom exceptions in this package inherit from this class, allowing callers to catch all yalab-procedures errors with a single except clause if desired. """ pass
[docs] class ProcedureExecutionError(YALabProcedureError): """Raised when a procedure fails during execution. Parameters ---------- procedure_name : str Name of the procedure that failed. message : str The error message. original_error : Optional[Exception], optional The underlying exception that caused the failure, if any, by default None. """ def __init__( self, procedure_name: str, message: str, original_error: Optional[Exception] = None, ): self.procedure_name = procedure_name self.original_error = original_error super().__init__(f"{procedure_name} failed: {message}")
[docs] class ProcedureConfigurationError(YALabProcedureError): """Raised when procedure configuration is invalid. This includes missing required inputs, invalid input combinations, or configuration that cannot be used together. """ pass
[docs] class InputValidationError(YALabProcedureError): """Raised when input validation fails. This is raised during pre-flight checks when inputs don't meet the requirements for procedure execution. """ pass
[docs] class OutputCollectionError(YALabProcedureError): """Raised when expected outputs are not found after procedure execution. This indicates the procedure may have failed silently or produced unexpected output structure. """ pass
[docs] class DockerExecutionError(ProcedureExecutionError): """Raised when a Docker-based procedure fails. Parameters ---------- procedure_name : str Name of the procedure that failed. container : str The Docker image/container that was running. exit_code : int The exit code returned by the Docker container. stderr : str Standard error output from the container. """ def __init__( self, procedure_name: str, container: str, exit_code: int, stderr: str, ): self.container = container self.exit_code = exit_code self.stderr = stderr message = f"Docker container '{container}' exited with code {exit_code}" if stderr: # Truncate very long stderr for the message stderr_preview = stderr[:500] + "..." if len(stderr) > 500 else stderr message += f": {stderr_preview}" super().__init__(procedure_name, message)
[docs] class FreeSurferLicenseError(ProcedureConfigurationError): """Raised when FreeSurfer license file cannot be found. This is a specific configuration error for procedures that require FreeSurfer and cannot locate a valid license file. """ def __init__(self, message: Optional[str] = None): if message is None: message = ( "FreeSurfer license not found. Set FS_LICENSE or FREESURFER_HOME " "environment variable, or provide fs_license_file parameter." ) super().__init__(message)
[docs] class BIDSValidationError(YALabProcedureError): """Raised when BIDS dataset validation fails. This indicates the input data does not conform to BIDS specification requirements for the procedure. """ pass
[docs] class DependencyError(YALabProcedureError): """Raised when a required external dependency is not available. This includes missing Docker, missing command-line tools, or unavailable Python packages. Parameters ---------- dependency : str The name of the missing dependency. message : Optional[str], optional The error message, by default None. """ def __init__(self, dependency: str, message: Optional[str] = None): self.dependency = dependency if message is None: message = f"Required dependency '{dependency}' is not available" super().__init__(message)
# Alias for backwards compatibility ProcedureError = YALabProcedureError