55
66import logging
77import sys
8+ import traceback
89
910from google .cloud import bigquery
1011
@@ -28,6 +29,42 @@ def _get_bq_client() -> bigquery.Client:
2829 setattr (_get_bq_client , "client" , bigquery .Client ())
2930 return getattr (_get_bq_client , "client" )
3031
32+ ################################################################
33+ ### rollback exception handler for deleting processing_history entries
34+
35+ rollback_rows = []
36+
37+
38+ def sp_rollback_exception_handler (exc_type , exc_value , exc_traceback ):
39+ """
40+ https://docs.python.org/3/library/sys.html#sys.excepthook
41+ """
42+ exception_details = "" .join (
43+ traceback .format_exception (exc_type , exc_value , exc_traceback )
44+ )
45+
46+ # Log the exception
47+ _logger .error ("Uncaught exception:\n %s" , exception_details )
48+
49+ _logger .warning ("Rolling back started SP ingest rows." )
50+ for row in rollback_rows :
51+ _logger .info (f"Rolling back row: { row } " )
52+ c = processing_history .delete (
53+ processing_history_table = row ["processing_history_table" ],
54+ release_tag = row ["release_tag" ],
55+ file_type = row ["file_type" ],
56+ xml_release_date = row ["xml_release_date" ],
57+ client = _get_bq_client (),
58+ )
59+ _logger .info (f"Deleted { c } rows from processing_history." )
60+
61+ # Call the default exception handler
62+ sys .__excepthook__ (exc_type , exc_value , exc_traceback )
63+
64+ # Add the exception handler as the global exception handler.
65+ # NOTE: this modifies global state and will affect all subsequent exceptions
66+ # in this script or any other script which imports this script.
67+ sys .excepthook = sp_rollback_exception_handler
3168
3269################################################################
3370### Initialization code
@@ -84,6 +121,17 @@ def _get_bq_client() -> bigquery.Client:
84121 """
85122 _logger .info (msg )
86123
124+ # Add the started row to the rollback list
125+ rollback_rows .append (
126+ {
127+ "processing_history_table" : processing_history_table ,
128+ "release_tag" : vcv_pipeline_version ,
129+ "file_type" : env .file_format_mode ,
130+ "xml_release_date" : str (vcv_xml_release_date ),
131+ "client" : _get_bq_client (),
132+ }
133+ )
134+
87135# Now process individual rows
88136for row in rows_to_ingest :
89137 _logger .info (row )
@@ -116,21 +164,19 @@ def _get_bq_client() -> bigquery.Client:
116164 _logger .info (msg )
117165 send_slack_message (msg )
118166 except Exception as e :
119- processing_history .write_started (
120- processing_history_table = processing_history_table ,
121- release_date = None ,
122- release_tag = vcv_pipeline_version ,
123- schema_version = schema_version ,
124- file_type = ClinVarIngestFileFormat (env .file_format_mode ),
125- client = _get_bq_client (),
126- bucket_dir = vcv_bucket_dir ,
127- xml_release_date = str (vcv_xml_release_date ),
128- error_if_exists = False ,
129- )
130167 msg = f"""
131168 Stored procedure execution failed for release dated { vcv_xml_release_date } version
132169 { vcv_pipeline_version } .
133170 """
134171 _logger .error (msg )
135172 send_slack_message (msg )
136173 raise e
174+
175+
176+ # Remove the started row from the rollback list, since this ingest has succeeded
177+ rollback_rows = [
178+ row
179+ for row in rollback_rows
180+ if row ["xml_release_date" ] != str (vcv_xml_release_date )
181+ or row ["release_tag" ] != vcv_pipeline_version
182+ ]
0 commit comments