From f8b1580fb082c4cfe08585a2c043aee2fd215d54 Mon Sep 17 00:00:00 2001 From: David Roe Date: Sat, 14 Feb 2026 14:34:35 -0500 Subject: [PATCH 1/2] Catch errors in completeness framework --- lmfdb/utils/search_wrapper.py | 68 +++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/lmfdb/utils/search_wrapper.py b/lmfdb/utils/search_wrapper.py index 14438d0561..d8d9a2f9cf 100644 --- a/lmfdb/utils/search_wrapper.py +++ b/lmfdb/utils/search_wrapper.py @@ -271,36 +271,44 @@ def __call__(self, info): # Display warning message if user searched on column(s) with null values if query: nulls = table.stats.null_counts() - complete, msg, caveat = results_complete(table.search_table, query, table._db, info.get("search_array")) - if complete: - flash_success("The results below are complete, since the LMFDB contains all " + msg) - elif nulls: # TODO: We already run a version of this inside results_complete. Should be combined - search_columns = table._columns_searched(query) - nulls = {col: cnt for col, cnt in nulls.items() if col in search_columns} - col_display = {} - if "search_array" in info: - for row in info["search_array"].refine_array: - if isinstance(row, (list, tuple)): - for item in row: - if hasattr(item, "name") and hasattr(item, "label"): - col_display[item.name] = item.label - for col, cnt in list(nulls.items()): - override = info["search_array"].null_column_explanations.get(col) - if override is False: - del nulls[col] - elif override: - nulls[col] = override - else: - nulls[col] = f"{col_display.get(col, col)} ({cnt} objects)" - else: - for col, cnt in list(nulls.items()): - nulls[col] = f"{col} ({cnt} objects)" - if nulls: - msg = 'Search results may be incomplete due to uncomputed quantities: ' - msg += ", ".join(nulls.values()) - flash_info(msg) - if caveat: - flash_info("The completeness " + caveat) + try: + complete, msg, caveat = results_complete(table.search_table, query, table._db, info.get("search_array")) + if complete: + flash_success("The results below are complete, since the LMFDB contains all " + msg) + elif nulls: # TODO: We already run a version of this inside results_complete. Should be combined + search_columns = table._columns_searched(query) + nulls = {col: cnt for col, cnt in nulls.items() if col in search_columns} + col_display = {} + if "search_array" in info: + for row in info["search_array"].refine_array: + if isinstance(row, (list, tuple)): + for item in row: + if hasattr(item, "name") and hasattr(item, "label"): + col_display[item.name] = item.label + for col, cnt in list(nulls.items()): + override = info["search_array"].null_column_explanations.get(col) + if override is False: + del nulls[col] + elif override: + nulls[col] = override + else: + nulls[col] = f"{col_display.get(col, col)} ({cnt} objects)" + else: + for col, cnt in list(nulls.items()): + nulls[col] = f"{col} ({cnt} objects)" + if nulls: + msg = 'Search results may be incomplete due to uncomputed quantities: ' + msg += ", ".join(nulls.values()) + flash_info(msg) + if caveat: + flash_info("The completeness " + caveat) + except Exception as err: + from lmfdb.logger import critical + import traceback + msg = f"There was an error in the completeness checking code, so the search results below may or may not be complete: \n{err}" + flash_info(msg) + msg += "\n" + traceback.format_exc() + critical(msg) return render_template(template, info=info, title=title, **template_kwds) From a3f18f01442d93c333ce91a7b8d1e21fcf67d3fe Mon Sep 17 00:00:00 2001 From: David Roe Date: Fri, 20 Feb 2026 12:55:49 -0500 Subject: [PATCH 2/2] Log using app.logger --- lmfdb/utils/search_wrapper.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lmfdb/utils/search_wrapper.py b/lmfdb/utils/search_wrapper.py index d8d9a2f9cf..c0835df2b4 100644 --- a/lmfdb/utils/search_wrapper.py +++ b/lmfdb/utils/search_wrapper.py @@ -5,7 +5,7 @@ from sage.misc.decorators import decorator_keywords from sage.misc.cachefunc import cached_function -from lmfdb.app import ctx_proc_userdata, is_debug_mode +from lmfdb.app import app, ctx_proc_userdata, is_debug_mode from lmfdb.utils.search_parsing import parse_start, parse_count, SearchParsingError from lmfdb.utils.utilities import flash_error, flash_info, flash_success, to_dict from lmfdb.utils.completeness import results_complete @@ -303,12 +303,11 @@ def __call__(self, info): if caveat: flash_info("The completeness " + caveat) except Exception as err: - from lmfdb.logger import critical import traceback msg = f"There was an error in the completeness checking code, so the search results below may or may not be complete: \n{err}" flash_info(msg) msg += "\n" + traceback.format_exc() - critical(msg) + app.logger.warning(msg) return render_template(template, info=info, title=title, **template_kwds)