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)
Issue:
Currently, device functions like
create_magnet()orcreate_wire()catchValidationErrorinternally 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 thetry/exceptlogic in the application-level code.create_<device>functions no longer catchValidationErrorinternallyNoneor raise a custom exception, based on contextRefactored code example:
reader.py
tmit_loss.py
Log example: