From 325dafacbc63b45ebd2e7903ae81dfa08d9338d2 Mon Sep 17 00:00:00 2001 From: Smittix Date: Tue, 3 Mar 2026 20:46:14 +0000 Subject: [PATCH] fix: improve startup error reporting with full stderr logging and dependency pre-check Radiosonde route now runs a quick import check before launching the full subprocess, catching missing Python dependencies immediately with a clear message instead of a truncated traceback. Error messages are context-aware: import errors suggest re-running setup.sh rather than checking SDR connections. Increased stderr truncation limit from 200 to 500 chars and added full stderr logging via logger.error() across all affected routes (radiosonde, ais, aprs, acars, vdl2) for easier debugging. Closes #173 Co-Authored-By: Claude Opus 4.6 --- routes/acars.py | 6 ++++-- routes/ais.py | 4 +++- routes/aprs.py | 4 +++- routes/radiosonde.py | 38 ++++++++++++++++++++++++++++++++++++-- routes/vdl2.py | 4 +++- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/routes/acars.py b/routes/acars.py index 88b91c7..f7141eb 100644 --- a/routes/acars.py +++ b/routes/acars.py @@ -366,9 +366,11 @@ def start_acars() -> Response: stderr = '' if process.stderr: stderr = process.stderr.read().decode('utf-8', errors='replace') - error_msg = f'acarsdec failed to start' if stderr: - error_msg += f': {stderr[:200]}' + logger.error(f"acarsdec stderr:\n{stderr}") + error_msg = 'acarsdec failed to start' + if stderr: + error_msg += f': {stderr[:500]}' logger.error(error_msg) return jsonify({'status': 'error', 'message': error_msg}), 500 diff --git a/routes/ais.py b/routes/ais.py index 6281172..377300b 100644 --- a/routes/ais.py +++ b/routes/ais.py @@ -450,9 +450,11 @@ def start_ais(): stderr_output = app_module.ais_process.stderr.read().decode('utf-8', errors='ignore').strip() except Exception: pass + if stderr_output: + logger.error(f"AIS-catcher stderr:\n{stderr_output}") error_msg = 'AIS-catcher failed to start. Check SDR device connection.' if stderr_output: - error_msg += f' Error: {stderr_output[:200]}' + error_msg += f' Error: {stderr_output[:500]}' return jsonify({'status': 'error', 'message': error_msg}), 500 ais_running = True diff --git a/routes/aprs.py b/routes/aprs.py index 0961487..4c40b02 100644 --- a/routes/aprs.py +++ b/routes/aprs.py @@ -1870,9 +1870,11 @@ def start_aprs() -> Response: stderr_output = remaining.decode('utf-8', errors='replace').strip() except Exception: pass + if stderr_output: + logger.error(f"rtl_fm stderr:\n{stderr_output}") error_msg = f'rtl_fm failed to start (exit code {rtl_process.returncode})' if stderr_output: - error_msg += f': {stderr_output[:200]}' + error_msg += f': {stderr_output[:500]}' logger.error(error_msg) try: os.close(master_fd) diff --git a/routes/radiosonde.py b/routes/radiosonde.py index c2f33e9..4c392ad 100644 --- a/routes/radiosonde.py +++ b/routes/radiosonde.py @@ -586,6 +586,26 @@ def start_radiosonde(): # Set cwd to the auto_rx directory so 'from autorx.scan import ...' works auto_rx_dir = os.path.dirname(os.path.abspath(auto_rx_path)) + # Quick dependency check before launching the full process + if auto_rx_path.endswith('.py'): + dep_check = subprocess.run( + [sys.executable, '-c', 'import autorx.scan'], + cwd=auto_rx_dir, + capture_output=True, + timeout=10, + ) + if dep_check.returncode != 0: + dep_error = dep_check.stderr.decode('utf-8', errors='ignore').strip() + logger.error(f"radiosonde_auto_rx dependency check failed:\n{dep_error}") + app_module.release_sdr_device(device_int, sdr_type_str) + return jsonify({ + 'status': 'error', + 'message': ( + 'radiosonde_auto_rx dependencies not satisfied. ' + f'Re-run setup.sh to install. Error: {dep_error[:500]}' + ), + }), 500 + try: logger.info(f"Starting radiosonde_auto_rx: {' '.join(cmd)}") app_module.radiosonde_process = subprocess.Popen( @@ -609,9 +629,23 @@ def start_radiosonde(): ).strip() except Exception: pass - error_msg = 'radiosonde_auto_rx failed to start. Check SDR device connection.' if stderr_output: - error_msg += f' Error: {stderr_output[:200]}' + logger.error(f"radiosonde_auto_rx stderr:\n{stderr_output}") + if stderr_output and ( + 'ImportError' in stderr_output + or 'ModuleNotFoundError' in stderr_output + ): + error_msg = ( + 'radiosonde_auto_rx failed to start due to missing Python ' + 'dependencies. Re-run setup.sh or reinstall radiosonde_auto_rx.' + ) + else: + error_msg = ( + 'radiosonde_auto_rx failed to start. ' + 'Check SDR device connection.' + ) + if stderr_output: + error_msg += f' Error: {stderr_output[:500]}' return jsonify({'status': 'error', 'message': error_msg}), 500 radiosonde_running = True diff --git a/routes/vdl2.py b/routes/vdl2.py index 2d0eae2..853ebbe 100644 --- a/routes/vdl2.py +++ b/routes/vdl2.py @@ -306,9 +306,11 @@ def start_vdl2() -> Response: stderr = '' if process.stderr: stderr = process.stderr.read().decode('utf-8', errors='replace') + if stderr: + logger.error(f"dumpvdl2 stderr:\n{stderr}") error_msg = 'dumpvdl2 failed to start' if stderr: - error_msg += f': {stderr[:200]}' + error_msg += f': {stderr[:500]}' logger.error(error_msg) return jsonify({'status': 'error', 'message': error_msg}), 500