mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
v2.26.5: fix database errors crashing entire UI (#190)
get_setting() now catches sqlite3.OperationalError and returns the default value. Previously, an inaccessible database (e.g. root-owned instance/ from sudo) caused inject_offline_settings to crash every page render with 500 Internal Server Error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,13 @@
|
||||
|
||||
All notable changes to iNTERCEPT will be documented in this file.
|
||||
|
||||
## [2.26.5] - 2026-03-14
|
||||
|
||||
### Fixed
|
||||
- **Database errors crash entire UI** — `get_setting()` now catches `sqlite3.OperationalError` and returns the default value instead of propagating the exception. Previously, if the database was inaccessible (e.g. root-owned `instance/` directory from running with `sudo`), the `inject_offline_settings` context processor would crash every page render with a 500 Internal Server Error. (#190)
|
||||
|
||||
---
|
||||
|
||||
## [2.26.4] - 2026-03-14
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -7,10 +7,17 @@ import os
|
||||
import sys
|
||||
|
||||
# Application version
|
||||
VERSION = "2.26.4"
|
||||
VERSION = "2.26.5"
|
||||
|
||||
# Changelog - latest release notes (shown on welcome screen)
|
||||
CHANGELOG = [
|
||||
{
|
||||
"version": "2.26.5",
|
||||
"date": "March 2026",
|
||||
"highlights": [
|
||||
"Fix database errors crashing the entire UI — pages now degrade gracefully",
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "2.26.4",
|
||||
"date": "March 2026",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "intercept"
|
||||
version = "2.26.4"
|
||||
version = "2.26.5"
|
||||
description = "Signal Intelligence Platform - Pager/433MHz/ADS-B/Satellite/WiFi/Bluetooth"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
|
||||
@@ -661,32 +661,36 @@ def get_setting(key: str, default: Any = None) -> Any:
|
||||
Returns:
|
||||
Setting value (auto-converted from JSON for complex types)
|
||||
"""
|
||||
with get_db() as conn:
|
||||
cursor = conn.execute(
|
||||
'SELECT value, value_type FROM settings WHERE key = ?',
|
||||
(key,)
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
try:
|
||||
with get_db() as conn:
|
||||
cursor = conn.execute(
|
||||
'SELECT value, value_type FROM settings WHERE key = ?',
|
||||
(key,)
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
|
||||
if row is None:
|
||||
return default
|
||||
|
||||
value, value_type = row['value'], row['value_type']
|
||||
|
||||
# Convert based on type
|
||||
if value_type == 'json':
|
||||
try:
|
||||
return json.loads(value)
|
||||
except json.JSONDecodeError:
|
||||
if row is None:
|
||||
return default
|
||||
elif value_type == 'int':
|
||||
return int(value)
|
||||
elif value_type == 'float':
|
||||
return float(value)
|
||||
elif value_type == 'bool':
|
||||
return value.lower() in ('true', '1', 'yes')
|
||||
else:
|
||||
return value
|
||||
|
||||
value, value_type = row['value'], row['value_type']
|
||||
|
||||
# Convert based on type
|
||||
if value_type == 'json':
|
||||
try:
|
||||
return json.loads(value)
|
||||
except json.JSONDecodeError:
|
||||
return default
|
||||
elif value_type == 'int':
|
||||
return int(value)
|
||||
elif value_type == 'float':
|
||||
return float(value)
|
||||
elif value_type == 'bool':
|
||||
return value.lower() in ('true', '1', 'yes')
|
||||
else:
|
||||
return value
|
||||
except sqlite3.OperationalError:
|
||||
logger.warning("Database unavailable reading setting '%s', using default", key)
|
||||
return default
|
||||
|
||||
|
||||
def set_setting(key: str, value: Any) -> None:
|
||||
|
||||
Reference in New Issue
Block a user