1010
1111from services .dicom import FAILURE , SUCCESS
1212from services .dicom .image_compressor import ImageCompressor
13+ from services .dicom .validation_failure_notifier import ValidationFailureNotifier
1314from services .dicom .validator import DicomValidationError , DicomValidator
14- from services .storage import InstanceExistsError , PACSStorage
15+ from services .storage import InstanceExistsError , MWLStorage , PACSStorage
1516
1617logger = logging .getLogger (__name__ )
1718
@@ -27,10 +28,14 @@ def __init__(
2728 storage : PACSStorage ,
2829 compressor : ImageCompressor | None = None ,
2930 validator : DicomValidator | None = None ,
31+ mwl_storage : MWLStorage | None = None ,
32+ notifier : ValidationFailureNotifier | None = None ,
3033 ):
3134 self .storage = storage
3235 self .compressor = compressor or ImageCompressor ()
3336 self .validator = validator or DicomValidator ()
37+ self .mwl_storage = mwl_storage
38+ self .notifier = notifier
3439
3540 def call (self , event : Event ) -> int :
3641 try :
@@ -42,24 +47,27 @@ def call(self, event: Event) -> int:
4247 return FAILURE
4348
4449 sop_instance_uid = ds .get ("SOPInstanceUID" , "" )
50+ accession_number = ds .get ("AccessionNumber" , "" )
51+ patient_id = ds .get ("PatientID" )
52+ patient_name = str (ds .get ("PatientName" , "" ))
53+
4554 if not sop_instance_uid :
4655 logger .error ("Missing SOPInstanceUID" )
56+ self ._notify_failure (accession_number , "Missing SOPInstanceUID" )
4757 return FAILURE
4858
49- patient_id = ds .get ("PatientID" )
5059 if not patient_id :
5160 logger .error ("Missing PatientID" )
61+ self ._notify_failure (accession_number , "Missing PatientID" )
5262 return FAILURE
5363
54- accession_number = ds .get ("AccessionNumber" , "" )
55- patient_name = str (ds .get ("PatientName" , "" ))
56-
5764 # Validate dataset before compression
5865 try :
5966 self .validator .validate_dataset (ds )
6067 self .validator .validate_pixel_data (ds )
6168 except DicomValidationError as e :
6269 logger .error (f"DICOM validation failed: { e } " )
70+ self ._notify_failure (accession_number , f"DICOM validation failed: { e } " )
6371 return FAILURE
6472
6573 # Compress dataset before storing
@@ -71,6 +79,7 @@ def call(self, event: Event) -> int:
7179 self .validator .validate_bytes (dicom_bytes )
7280 except DicomValidationError as e :
7381 logger .error (f"Serialized DICOM invalid: { e } " )
82+ self ._notify_failure (accession_number , f"Serialized DICOM invalid: { e } " )
7483 return FAILURE
7584
7685 self .storage .store_instance (
@@ -100,3 +109,16 @@ def dataset_to_bytes(self, ds: Dataset) -> bytes:
100109 dcmwrite (buffer , ds , enforce_file_format = True )
101110 buffer .seek (0 )
102111 return buffer .read ()
112+
113+ def _notify_failure (self , accession_number : str , error : str ) -> None :
114+ if not self .mwl_storage or not self .notifier :
115+ return
116+
117+ source_message_id = self .mwl_storage .get_source_message_id (accession_number )
118+ if not source_message_id :
119+ logger .warning (
120+ f"Cannot report validation failure: no worklist item found for accession { accession_number !r} "
121+ )
122+ return
123+
124+ self .notifier .notify (source_message_id , error )
0 commit comments