Skip to content

Commit f545e5c

Browse files
refactor exception handling
1 parent d84217f commit f545e5c

File tree

3 files changed

+347
-2
lines changed

3 files changed

+347
-2
lines changed

CI_JobHistory.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from tabulate import tabulate
44
import re
55
from datetime import datetime,timedelta
6-
import monitor
6+
import monitor_compact as monitor
77
import argparse
88
import configparser
99

monitor.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,11 @@ def get_brief_job_info(build_list,prow_ci_name,zone=None,job_filter='All'):
12621262
continue
12631263
build_status = check_job_status(build)
12641264
cluster_status=cluster_deploy_status(build)
1265-
sensitive_info_expose_status=check_if_sensitive_info_exposed(build)
1265+
try:
1266+
sensitive_info_expose_status = check_if_sensitive_info_exposed(build)
1267+
except RuntimeError as e:
1268+
print(f"Warning: Could not check sensitive info exposure: {e}")
1269+
sensitive_info_expose_status = False
12661270
i=i+1
12671271
job_dict = {}
12681272
job_dict["Job"] = prow_ci_name
@@ -1340,6 +1344,15 @@ def get_detailed_job_info(build_list, prow_ci_name, zone=None, job_filter="all")
13401344
print("Build start time:", time)
13411345
except (requests.exceptions.RequestException, KeyError, ValueError) as e:
13421346
print("Error fetching build time:", e)
1347+
<<<<<<< HEAD
1348+
=======
1349+
build_status = check_job_status(build)
1350+
try:
1351+
sensitive_info_expose_status = check_if_sensitive_info_exposed(build)
1352+
except RuntimeError as e:
1353+
print(f"Warning: Could not check sensitive info exposure: {e}")
1354+
sensitive_info_expose_status = False # or decide what default behavior you want
1355+
>>>>>>> 2bb7328 (refactor exception handling)
13431356

13441357
build_status = check_job_status(build)
13451358
sensitive_info_expose_status = check_if_sensitive_info_exposed(build)

monitor_compact.py

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
# monitor_compat.py
2+
"""
3+
Compatibility wrapper for the monitor module that raises exceptions.
4+
This wrapper converts exceptions into legacy string/tuple return values so older
5+
callers don't need to be changed.
6+
"""
7+
8+
from typing import Tuple, List, Dict, Any
9+
import monitor
10+
11+
PROW_URL = None
12+
final_job_list = None
13+
14+
def _sync_module_attrs():
15+
global PROW_URL, final_job_list
16+
try:
17+
PROW_URL = monitor.PROW_URL
18+
except Exception:
19+
PROW_URL = None
20+
try:
21+
final_job_list = monitor.final_job_list
22+
except Exception:
23+
final_job_list = []
24+
25+
# initialize
26+
_sync_module_attrs()
27+
28+
# error mapping helpers
29+
def _err_str_from_exc(exc) -> str:
30+
# Map typed exceptions to legacy strings (best-effort)
31+
if isinstance(exc, monitor.ProwTimeoutError):
32+
return "Request timed out"
33+
if isinstance(exc, monitor.ProwFetchError):
34+
# many places previously used this message for network errors
35+
return "Error while sending request to url"
36+
if isinstance(exc, monitor.ProwParseError):
37+
# generic parse/error sentinel used in original file
38+
return "ERROR"
39+
# default fallback
40+
return "ERROR"
41+
42+
# Wrapped functions ---------------------------------------------------------
43+
44+
def fetch_release_date(release: str) -> str:
45+
try:
46+
return monitor.fetch_release_date(release)
47+
except Exception as e:
48+
return _err_str_from_exc(e)
49+
50+
def fetch_build_time(url: str) -> str:
51+
try:
52+
return monitor.fetch_build_time(url)
53+
except Exception as e:
54+
# original returned "Request timed out" or "Error while sending request to url"
55+
return _err_str_from_exc(e)
56+
57+
def set_prow_url(ci_job_type: str) -> str:
58+
return monitor.set_prow_url(ci_job_type)
59+
60+
def load_config(config_file: str) -> dict:
61+
# load_config raised on error before; original code exited on error,
62+
# but we will re-raise to keep behavior obvious
63+
return monitor.load_config(config_file)
64+
65+
def get_current_date():
66+
return monitor.get_current_date()
67+
68+
def parse_job_date(date: str):
69+
return monitor.parse_job_date(date)
70+
71+
def get_jobs(prow_link: str):
72+
try:
73+
return monitor.get_jobs(prow_link)
74+
except Exception as e:
75+
return _err_str_from_exc(e)
76+
77+
def get_n_recent_jobs(prow_link: str, n: int):
78+
try:
79+
return monitor.get_n_recent_jobs(prow_link, n)
80+
except Exception as e:
81+
return _err_str_from_exc(e)
82+
83+
def check_job_status(spy_link: str):
84+
try:
85+
return monitor.check_job_status(spy_link)
86+
except Exception as e:
87+
return _err_str_from_exc(e)
88+
89+
def cluster_deploy_status(spy_link: str):
90+
try:
91+
return monitor.cluster_deploy_status(spy_link)
92+
except Exception as e:
93+
return _err_str_from_exc(e)
94+
95+
def cluster_creation_error_analysis(spylink: str):
96+
try:
97+
return monitor.cluster_creation_error_analysis(spylink)
98+
except Exception as e:
99+
return _err_str_from_exc(e)
100+
101+
def check_if_gather_libvirt_dir_exists(spy_link: str, job_type: str):
102+
try:
103+
return monitor.check_if_gather_libvirt_dir_exists(spy_link, job_type)
104+
except Exception as e:
105+
return _err_str_from_exc(e)
106+
107+
def check_hypervisor_error(spy_link: str):
108+
try:
109+
return monitor.check_hypervisor_error(spy_link)
110+
except Exception as e:
111+
return _err_str_from_exc(e)
112+
113+
def check_if_sensitive_info_exposed(spy_link: str):
114+
try:
115+
return monitor.check_if_sensitive_info_exposed(spy_link)
116+
except Exception as e:
117+
# original function raised RuntimeError on underlying errors in strict variant;
118+
# in legacy it returned booleans or raised. We'll return False and preserve message by raising RuntimeError
119+
raise RuntimeError(f"Error in check_if_sensitive_info_exposed: {_err_str_from_exc(e)}")
120+
121+
def get_node_status(spy_link: str):
122+
try:
123+
return monitor.get_node_status(spy_link)
124+
except Exception as e:
125+
return _err_str_from_exc(e)
126+
127+
def check_node_crash(spy_link: str):
128+
try:
129+
return monitor.check_node_crash(spy_link)
130+
except Exception as e:
131+
return _err_str_from_exc(e)
132+
133+
def get_lease(build_log_response, job_platform: str):
134+
try:
135+
return monitor.get_lease(build_log_response, job_platform)
136+
except Exception as e:
137+
return "Failed to fetch lease information"
138+
139+
def get_nightly(build_log_url: str, build_log_response, job_platform: str):
140+
try:
141+
return monitor.get_nightly(build_log_url, build_log_response, job_platform)
142+
except Exception as e:
143+
return f"Unable to fetch nightly {job_platform} information - No match found"
144+
145+
def get_quota_and_nightly(spy_link: str):
146+
try:
147+
return monitor.get_quota_and_nightly(spy_link)
148+
except monitor.ProwTimeoutError as e:
149+
# original returned error strings but caller expects (lease, nightly) normally
150+
return ("Request timed out", None)
151+
except monitor.ProwFetchError as e:
152+
return ("Error while sending request to url", None)
153+
except Exception:
154+
return ("Failed to fetch lease information", None)
155+
156+
def job_classifier(spy_link: str):
157+
# stateless; just forward
158+
return monitor.job_classifier(spy_link)
159+
160+
def get_failed_monitor_testcases(spy_link: str, job_type: str) -> Tuple[List[str], str]:
161+
try:
162+
tcs = monitor.get_failed_monitor_testcases(spy_link, job_type)
163+
# strict variant returns list (or raises) — original returned (list, None) on success
164+
if isinstance(tcs, tuple):
165+
# if strict variant already returned (list,msg)
166+
return tcs
167+
return tcs, None
168+
except monitor.ProwTimeoutError as e:
169+
return [], "Request timed out"
170+
except monitor.ProwFetchError as e:
171+
return [], "Failed to get response from e2e-test directory url"
172+
except monitor.ProwParseError as e:
173+
return [], "Failed to parse the data from e2e-test log file!"
174+
except Exception:
175+
return [], "Failed to parse the data from e2e-test log file!"
176+
177+
def get_failed_monitor_testcases_from_xml(spy_link: str, job_type: str) -> Tuple[List[str], str]:
178+
try:
179+
tcs = monitor.get_failed_monitor_testcases_from_xml(spy_link, job_type)
180+
return tcs, None
181+
except monitor.ProwTimeoutError:
182+
return [], "Request timed out"
183+
except monitor.ProwFetchError:
184+
return [], "Failed to get response from e2e-test directory url"
185+
except monitor.ProwParseError:
186+
return [], "Failed to parse junit e2e log file!"
187+
except Exception:
188+
return [], "Monitor test file not found"
189+
190+
def get_testcase_frequency(spylinks, zone=None, tc_name=None):
191+
try:
192+
return monitor.get_testcase_frequency(spylinks, zone, tc_name)
193+
except Exception:
194+
return {}
195+
196+
def get_failed_e2e_testcases(spy_link: str, job_type: str) -> Tuple[List[str], str]:
197+
try:
198+
tcs = monitor.get_failed_e2e_testcases(spy_link, job_type)
199+
# strict version returns list; original returned (list, None)
200+
return tcs, None
201+
except monitor.ProwTimeoutError:
202+
return [], "Request timed out"
203+
except monitor.ProwFetchError:
204+
return [], "Failed to get response from e2e-test directory url"
205+
except monitor.ProwParseError:
206+
return [], "Failed to parse the data from e2e-test log file!"
207+
except Exception:
208+
return [], "Test summary file not found"
209+
210+
def get_junit_symptom_detection_testcase_failures(spy_link: str, job_type: str) -> Tuple[List[str], str]:
211+
try:
212+
tcs = monitor.get_junit_symptom_detection_testcase_failures(spy_link, job_type)
213+
return tcs, None
214+
except monitor.ProwTimeoutError:
215+
return [], "Request timed out"
216+
except monitor.ProwFetchError:
217+
return [], "Error while sending request to url"
218+
except monitor.ProwParseError:
219+
return [], "Failed to parse symptom detection e2e log file!"
220+
except Exception:
221+
return [], "Junit test summary file not found"
222+
223+
def get_all_failed_tc(spylink: str, jobtype: str):
224+
"""
225+
Return triple as original: (failed_tc_dict, failed_tc_count, error_object)
226+
original returned (failed_tc, failed_tc_count, error_object)
227+
"""
228+
try:
229+
failed_tc = monitor.get_all_failed_tc(spylink, jobtype)
230+
# strict version returns dict; original returned (dict, count, errors)
231+
if isinstance(failed_tc, tuple) and len(failed_tc) == 3:
232+
return failed_tc
233+
# if strict returns dict, compute counts and empty error object (best-effort)
234+
failed_tc_dict = failed_tc
235+
conformance = failed_tc_dict.get("conformance", [])
236+
monitor_list = failed_tc_dict.get("monitor", [])
237+
symptom = failed_tc_dict.get("symptom_detection", [])
238+
failed_tc_count = len(conformance) + len(monitor_list) + len(symptom)
239+
error_object = {"conformance": None, "monitor": None, "symptom_detection": None}
240+
return failed_tc_dict, failed_tc_count, error_object
241+
except monitor.ProwTimeoutError:
242+
return {}, 0, {"conformance": "Request timed out", "monitor": "Request timed out", "symptom_detection": "Request timed out"}
243+
except monitor.ProwFetchError:
244+
return {}, 0, {"conformance": "Error while sending request to url", "monitor": "Error while sending request to url", "symptom_detection": "Error while sending request to url"}
245+
except monitor.ProwParseError:
246+
return {}, 0, {"conformance": "Failed to parse the data from e2e-test log file!", "monitor": "Failed to parse the data from e2e-test log file!", "symptom_detection": "Failed to parse the data from e2e-test log file!"}
247+
except Exception:
248+
return {}, 0, {"conformance": "Test summary file not found", "monitor": "Test summary file not found", "symptom_detection": "Test summary file not found"}
249+
250+
def check_ts_exe_status(spylink: str, jobtype: str):
251+
try:
252+
return monitor.check_ts_exe_status(spylink, jobtype)
253+
except monitor.ProwTimeoutError:
254+
return "Request timed out"
255+
except monitor.ProwFetchError:
256+
return "Error while sending request to url"
257+
except monitor.ProwParseError:
258+
return "ERROR"
259+
except Exception:
260+
return "ERROR"
261+
262+
def print_all_failed_tc(spylink: str, jobtype: str):
263+
try:
264+
return monitor.print_all_failed_tc(spylink, jobtype)
265+
except monitor.ProwTimeoutError:
266+
return "Request timed out"
267+
except monitor.ProwFetchError:
268+
return "Error while sending request to url"
269+
except monitor.ProwParseError:
270+
return "ERROR"
271+
except Exception:
272+
return "ERROR"
273+
274+
def check_testcase_failure(spylink: str, job_type: str, testcase_name: str) -> bool:
275+
try:
276+
return monitor.check_testcase_failure(spylink, job_type, testcase_name)
277+
except Exception:
278+
# safe fallback: False (test not found / error)
279+
return False
280+
281+
def get_jobs_with_date(prowci_url: str, start_date, end_date):
282+
try:
283+
return monitor.get_jobs_with_date(prowci_url, start_date, end_date)
284+
except monitor.ProwTimeoutError:
285+
return "Request timed out"
286+
except monitor.ProwFetchError:
287+
return "Error while sending request to url"
288+
except monitor.ProwParseError:
289+
return "ERROR"
290+
except Exception:
291+
return "ERROR"
292+
293+
def get_next_page_first_build_date(ci_next_page_spylink: str, end_date):
294+
try:
295+
return monitor.get_next_page_first_build_date(ci_next_page_spylink, end_date)
296+
except monitor.ProwTimeoutError:
297+
return "Request timed out"
298+
except monitor.ProwFetchError:
299+
return "Error while sending request to url"
300+
except monitor.ProwParseError:
301+
return "ERROR"
302+
except Exception:
303+
return "ERROR"
304+
305+
def get_brief_job_info(build_list, prow_ci_name, zone=None):
306+
try:
307+
return monitor.get_brief_job_info(build_list, prow_ci_name, zone=zone)
308+
except monitor.ProwTimeoutError:
309+
# original returned printed message and empty list
310+
return []
311+
except monitor.ProwFetchError:
312+
return []
313+
except monitor.ProwParseError:
314+
return []
315+
except Exception:
316+
return []
317+
318+
def get_detailed_job_info(build_list, prow_ci_name, zone=None):
319+
try:
320+
return monitor.get_detailed_job_info(build_list, prow_ci_name, zone=zone)
321+
except monitor.ProwTimeoutError:
322+
return 1
323+
except monitor.ProwFetchError:
324+
return 1
325+
except monitor.ProwParseError:
326+
return 1
327+
except Exception:
328+
return 1
329+
330+
# Allow attribute access fallback to underlying strict module for constants etc.
331+
def __getattr__(name):
332+
return getattr(monitor, name)

0 commit comments

Comments
 (0)