From a94c6a291e9b89f2c0eec9da3072d56998e6d5d5 Mon Sep 17 00:00:00 2001 From: Ingo Ratsdorf Date: Wed, 10 Sep 2025 09:28:45 +1200 Subject: [PATCH 1/5] DB result iteration fix on empty result get_table_json would throw exceptions when trying to iterate over a NONE result, ie SQL query returned empty result. --- server/db/db_helper.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/db/db_helper.py b/server/db/db_helper.py index d1039aaa..fb628628 100755 --- a/server/db/db_helper.py +++ b/server/db/db_helper.py @@ -199,8 +199,12 @@ def get_table_json(sql, sql_query): mylog('verbose', ['[Database] - SQL ERROR: ', e]) return json_obj({}, []) # return empty object - result = {"data": [row_to_json(column_names, row) for row in rows]} - return json_obj(result, column_names) + if (rows): + result = {"data": [row_to_json(column_names, row) for row in rows]} + return json_obj(result, column_names) + else: + # the SQL query returned no rows + return json_obj({}, []) # return empty object #------------------------------------------------------------------------------- From 2836996a21a332fe7c76421f049ad44873ba5a7a Mon Sep 17 00:00:00 2001 From: Ingo Ratsdorf Date: Wed, 10 Sep 2025 10:21:32 +1200 Subject: [PATCH 2/5] Update server/db/db_helper.py Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- server/db/db_helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/db/db_helper.py b/server/db/db_helper.py index fb628628..809fa714 100755 --- a/server/db/db_helper.py +++ b/server/db/db_helper.py @@ -203,8 +203,8 @@ def get_table_json(sql, sql_query): result = {"data": [row_to_json(column_names, row) for row in rows]} return json_obj(result, column_names) else: - # the SQL query returned no rows - return json_obj({}, []) # return empty object + result = {"data": []} + return json_obj(result, column_names) #------------------------------------------------------------------------------- From 24eaf1e143276e27e11fe34a8158062991ebab1b Mon Sep 17 00:00:00 2001 From: Ingo Ratsdorf Date: Wed, 10 Sep 2025 12:25:30 +1200 Subject: [PATCH 3/5] fixed get_table_json This would throw a subsequent error ['[Database] - get_table_as_json ERROR:', TypeError("'NoneType' object is not iterable")] --- server/db/db_helper.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/server/db/db_helper.py b/server/db/db_helper.py index 809fa714..9cbb3da2 100755 --- a/server/db/db_helper.py +++ b/server/db/db_helper.py @@ -6,7 +6,8 @@ INSTALL_PATH="/app" sys.path.extend([f"{INSTALL_PATH}/server"]) from helper import if_byte_then_to_str -from logger import mylog +from logger import mylog + #------------------------------------------------------------------------------- # Return the SQL WHERE clause for filtering devices based on their status. @@ -41,7 +42,6 @@ def get_device_condition_by_status(device_status): return conditions.get(device_status, 'WHERE 1=0') - #------------------------------------------------------------------------------- # Creates a JSON-like dictionary from a database row def row_to_json(names, row): @@ -71,6 +71,7 @@ def row_to_json(names, row): return rowEntry + #------------------------------------------------------------------------------- def sanitize_SQL_input(val): """ @@ -116,7 +117,6 @@ def get_date_from_period(period): return period_sql - #------------------------------------------------------------------------------- def print_table_schema(db, table): """ @@ -195,16 +195,11 @@ def get_table_json(sql, sql_query): sql.execute(sql_query) column_names = [col[0] for col in sql.description] rows = sql.fetchall() + data = [row_to_json(column_names, row) for row in rows] if rows else [] + return json_obj({"data": data}, column_names if rows else []) except sqlite3.Error as e: mylog('verbose', ['[Database] - SQL ERROR: ', e]) - return json_obj({}, []) # return empty object - - if (rows): - result = {"data": [row_to_json(column_names, row) for row in rows]} - return json_obj(result, column_names) - else: - result = {"data": []} - return json_obj(result, column_names) + return json_obj({"data": []}, []) # return empty object #------------------------------------------------------------------------------- From 7f7b0a328f4b14e964c6bcd3aff29e54dc4a7cdf Mon Sep 17 00:00:00 2001 From: Ingo Ratsdorf Date: Wed, 10 Sep 2025 12:32:23 +1200 Subject: [PATCH 4/5] Another fix to get_table_json IIteration error is not a SQL error, so gotta catch generic errors, too --- server/db/db_helper.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/db/db_helper.py b/server/db/db_helper.py index 9cbb3da2..7c17de12 100755 --- a/server/db/db_helper.py +++ b/server/db/db_helper.py @@ -200,7 +200,9 @@ def get_table_json(sql, sql_query): except sqlite3.Error as e: mylog('verbose', ['[Database] - SQL ERROR: ', e]) return json_obj({"data": []}, []) # return empty object - + except Exception as e: + mylog('verbose', ['[Database] - Unexpected ERROR: ', e]) + return json_obj({"data": []}, []) #------------------------------------------------------------------------------- class json_obj: From ccec89f41960117ade538cdf2bd286f562fdc250 Mon Sep 17 00:00:00 2001 From: Ingo Ratsdorf Date: Wed, 10 Sep 2025 12:38:33 +1200 Subject: [PATCH 5/5] Final fix --- server/db/db_helper.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/server/db/db_helper.py b/server/db/db_helper.py index 7c17de12..55f39472 100755 --- a/server/db/db_helper.py +++ b/server/db/db_helper.py @@ -193,16 +193,21 @@ def get_table_json(sql, sql_query): """ try: sql.execute(sql_query) - column_names = [col[0] for col in sql.description] rows = sql.fetchall() - data = [row_to_json(column_names, row) for row in rows] if rows else [] - return json_obj({"data": data}, column_names if rows else []) + if (rows): + # We only return data if we actually got some out of SQLite + column_names = [col[0] for col in sql.description] + data = [row_to_json(column_names, row) for row in rows] + return json_obj({"data": data}, column_names) except sqlite3.Error as e: + # SQLite error, e.g. malformed query mylog('verbose', ['[Database] - SQL ERROR: ', e]) - return json_obj({"data": []}, []) # return empty object except Exception as e: + # Catch-all for other exceptions, e.g. iteration error mylog('verbose', ['[Database] - Unexpected ERROR: ', e]) - return json_obj({"data": []}, []) + + # In case of any error or no data, return empty object + return json_obj({"data": []}, []) #------------------------------------------------------------------------------- class json_obj: