Skip to content

Refactor create_<device> functions to raise errors to application level #1

Description

@kabanaty

Issue:

Currently, device functions like create_magnet() or create_wire() catch ValidationError internally and print the error. This prevents upstream scripts or applications from handling these errors appropriately. To improve modularity and error handling, we should refactor these functions to either raise a custom exception or return a structured error object while preserving the try/except logic in the application-level code.

  • create_<device> functions no longer catch ValidationError internally
  • Application-level code is responsible for handling failures
  • Logging and error reporting should be moved to the caller
  • Devices that fail validation should return None or raise a custom exception, based on context

Refactored code example:

reader.py

def create_bpm(area: str = None, name: str = None) -> Union[None, BPM, BPMCollection]:
    device_data = _device_data(area=area, device_type="bpms", name=name)
    if not device_data:
        return None
    if name:
        device_data.update({"name": name})
        return BPM(**device_data)
    else:
        return BPMCollection(**device_data)

tmit_loss.py

def create_bpms(self, bpms_elements):
        bpm_obj_dict = {}

        # Iterate through Dataframe of Elements and Areas
        for index, row in bpms_elements.iterrows():
            element = row["Element"]
            area = row["Area"]

            # Create an lcls-tools BPM object and append to dictionary
            # Key: Element Name
            # Value: lcls-tools BPM object
            try:
                bpm_obj_dict[element] = create_bpm(name=element, area=area)
            except ValidationError as e:
                logging.warning("Validation error creating %s. Continuing...", element)
                for err in e.errors():
                    loc = " -> ".join(str(i) for i in err["loc"])
                    logging.warning("%s: %s (%s)", loc, err["msg"], err["type"])
        
        return bpm_obj_dict

Log example:

2025-06-17 13:39:06,652 - INFO - Reserving BSA Buffer...
2025-06-17 13:39:11,932 - INFO - Reserved BSA Buffer 23
2025-06-17 13:39:11,933 - INFO - Creating device dictionary...
2025-06-17 13:39:22,740 - WARNING - Validation error creating BPMBP13. Continuing...
2025-06-17 13:39:22,740 - WARNING - controls_information -> PVs -> x: Field required (missing)
2025-06-17 13:39:22,740 - WARNING - controls_information -> PVs -> y: Field required (missing)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions