@@ -70,24 +70,21 @@ def file_level_validation(incoming_message_body: dict) -> dict:
7070 NOTE: If file level validation fails the source file is moved to the archive folder, the audit table is updated
7171 to reflect the file has been processed and the filename lambda is invoked with the next file in the queue.
7272 """
73+ message_id = None
74+ file_key = None
75+ created_at_formatted_string = None
76+
7377 try :
7478 message_id = incoming_message_body .get ("message_id" )
7579 vaccine = incoming_message_body .get ("vaccine_type" ).upper ()
7680 supplier = incoming_message_body .get ("supplier" ).upper ()
7781 file_key = incoming_message_body .get ("filename" )
7882 permission = incoming_message_body .get ("permission" )
7983 created_at_formatted_string = incoming_message_body .get ("created_at_formatted_string" )
80- encoder = incoming_message_body .get ("encoder " , "utf-8" )
84+ encoding = incoming_message_body .get ("encoding " , "utf-8" )
8185
8286 # Fetch the data
83- try :
84- csv_reader = get_csv_content_dict_reader (file_key , encoder = encoder )
85- validate_content_headers (csv_reader )
86- except UnicodeDecodeError as e :
87- logger .warning ("Invalid Encoding detected: %s" , e )
88- # retry with cp1252 encoding
89- csv_reader = get_csv_content_dict_reader (file_key , encoder = "cp1252" )
90- validate_content_headers (csv_reader )
87+ csv_reader = get_validated_csv_reader (file_key , encoding = encoding )
9188
9289 # Validate has permission to perform at least one of the requested actions
9390 allowed_operations_set = get_permitted_operations (supplier , vaccine , permission )
@@ -110,24 +107,48 @@ def file_level_validation(incoming_message_body: dict) -> dict:
110107 }
111108
112109 except Exception as error :
113- logger .error ("Error in file_level_validation: %s" , error )
114-
115- # NOTE: The Exception may occur before the file_id, file_key and created_at_formatted_string are assigned
116- message_id = message_id or "Unable to ascertain message_id"
117- file_key = file_key or "Unable to ascertain file_key"
118- created_at_formatted_string = created_at_formatted_string or "Unable to ascertain created_at_formatted_string"
119- make_and_upload_ack_file (message_id , file_key , False , False , created_at_formatted_string )
120- file_status = (
121- f"{ FileStatus .NOT_PROCESSED } - { FileNotProcessedReason .UNAUTHORISED } "
122- if isinstance (error , NoOperationPermissions )
123- else FileStatus .FAILED
110+ handle_file_level_validation_exception (
111+ error , message_id = message_id , file_key = file_key , created_at_formatted_string = created_at_formatted_string
124112 )
113+ raise
125114
126- try :
127- move_file (SOURCE_BUCKET_NAME , file_key , f"{ ARCHIVE_DIR_NAME } /{ file_key } " )
128- except Exception as move_file_error :
129- logger .error ("Failed to move file to archive: %s" , move_file_error )
130115
131- # Update the audit table
132- update_audit_table_status (file_key , message_id , file_status , error_details = str (error ))
133- raise
116+ def get_validated_csv_reader (file_key : str , encoding : str = "utf-8" ) -> DictReader :
117+ """Helper function to get a validated CSV DictReader object."""
118+ try :
119+ csv_reader = get_csv_content_dict_reader (file_key , encoding = encoding )
120+ validate_content_headers (csv_reader )
121+ return csv_reader
122+ except UnicodeDecodeError as e :
123+ logger .warning ("Invalid Encoding detected: %s" , e )
124+ # Retry using cp-1252 encoding if the expected utf-8 fails
125+ # This is a known issue with a supplier - see VED-754 for details
126+ csv_reader = get_csv_content_dict_reader (file_key , encoding = "cp1252" )
127+
128+ validate_content_headers (csv_reader )
129+ return csv_reader
130+
131+
132+ def handle_file_level_validation_exception (
133+ error : Exception , message_id : str | None , file_key : str | None , created_at_formatted_string : str | None
134+ ) -> None :
135+ logger .error ("Error in file_level_validation: %s" , error )
136+
137+ # NOTE: The Exception may occur before the file_id, file_key and created_at_formatted_string are assigned
138+ message_id = message_id or "Unable to ascertain message_id"
139+ file_key = file_key or "Unable to ascertain file_key"
140+ created_at_formatted_string = created_at_formatted_string or "Unable to ascertain created_at_formatted_string"
141+ make_and_upload_ack_file (message_id , file_key , False , False , created_at_formatted_string )
142+ file_status = (
143+ f"{ FileStatus .NOT_PROCESSED } - { FileNotProcessedReason .UNAUTHORISED } "
144+ if isinstance (error , NoOperationPermissions )
145+ else FileStatus .FAILED
146+ )
147+
148+ try :
149+ move_file (SOURCE_BUCKET_NAME , file_key , f"{ ARCHIVE_DIR_NAME } /{ file_key } " )
150+ except Exception as move_file_error :
151+ logger .error ("Failed to move file to archive: %s" , move_file_error )
152+
153+ # Update the audit table
154+ update_audit_table_status (file_key , message_id , file_status , error_details = str (error ))
0 commit comments