diff --git a/scripts/tier2/artifacts/result_migration_app_controller_20260618/inspect_sites.py b/scripts/tier2/artifacts/result_migration_app_controller_20260618/inspect_sites.py new file mode 100644 index 00000000..1a138a62 --- /dev/null +++ b/scripts/tier2/artifacts/result_migration_app_controller_20260618/inspect_sites.py @@ -0,0 +1,16 @@ +import json +import subprocess +r = subprocess.run(['uv', 'run', 'python', 'scripts/audit_exception_handling.py', '--json'], capture_output=True, text=True) +data = json.loads(r.stdout) +app = [f for f in data['files'] if 'app_controller' in f.get('filename', '')][0] +findings = app['findings'] +broad = [f for f in findings if f.get('category') == 'INTERNAL_BROAD_CATCH'] +# Batch 1: L539, L581, L2048, L2070, L2083 +for line_num in [539, 581, 2048, 2070, 2083]: + matches = [f for f in broad if f.get('line') == line_num] + if matches: + f = matches[0] + ctx = f.get('context', '') + print(f'=== L{line_num} (category: {f.get("category", "")}, kind: {f.get("kind", "")}) ===') + print(f' context: {ctx[:300]}') + print() diff --git a/src/app_controller.py b/src/app_controller.py index 2e0d4527..a1e22aca 100644 --- a/src/app_controller.py +++ b/src/app_controller.py @@ -38,7 +38,7 @@ from src import shell_runner from src import theme_2 as theme from src import thinking_parser from src import tool_presets -from src.result_types import Result, ErrorInfo, ErrorKind +from src.result_types import Result, ErrorInfo, ErrorKind, OK from src.context_presets import ContextPresetManager from src.file_cache import ASTParser @@ -529,17 +529,24 @@ def _handle_show_track_proposal(controller: 'AppController', task: dict): controller.proposed_tracks = task.get("payload", []) controller._show_track_proposal_modal = True -def _handle_custom_callback(controller: 'AppController', task: dict): +def _handle_custom_callback(controller: 'AppController', task: dict) -> Result[None]: """[SDM: AppController._handle_custom_callback]""" cb = task.get("callback") args = task.get("args", []) if callable(cb): try: cb(*args) - except Exception as e: - print(f"Error in direct custom callback: {e}") + except (TypeError, ValueError, AttributeError, KeyError, IndexError, RuntimeError, OSError) as e: + logging.getLogger(__name__).debug("custom callback error: %s", e, extra={"source": "app_controller._handle_custom_callback"}) + return Result(data=None, errors=[ErrorInfo( + kind=ErrorKind.INTERNAL, + message=str(e), + source="app_controller._handle_custom_callback", + original=e, + )]) elif cb in controller._predefined_callbacks: controller._predefined_callbacks[cb](*args) + return OK def _handle_set_value(controller: 'AppController', task: dict): """[SDM: AppController._handle_set_value]""" @@ -562,7 +569,7 @@ def _handle_set_value(controller: 'AppController', task: dict): new_dict = {**current, key: value} setattr(controller, attr_name, new_dict) -def _handle_click(controller: 'AppController', task: dict): +def _handle_click(controller: 'AppController', task: dict) -> Result[None]: """[SDM: AppController._handle_click]""" item = task.get("item") user_data = task.get("user_data") @@ -578,8 +585,19 @@ def _handle_click(controller: 'AppController', task: dict): func(user_data=user_data) else: func() - except Exception: - func() + return OK + except (TypeError, ValueError, AttributeError, KeyError, IndexError, RuntimeError) as e: + logging.getLogger(__name__).debug("click handler error, trying no-arg fallback: %s", e, extra={"source": "app_controller._handle_click"}) + try: + func() + except (TypeError, ValueError, AttributeError, KeyError, IndexError, RuntimeError) as e2: + return Result(data=None, errors=[ErrorInfo( + kind=ErrorKind.INTERNAL, + message=str(e2), + source="app_controller._handle_click", + original=e2, + )]) + return OK def _handle_drag(controller: 'AppController', task: dict): """[SDM: AppController._handle_drag]""" @@ -1999,7 +2017,7 @@ class AppController: if not old_call['result']: old_call['result'] = output break - + if kind == 'response' and 'usage' in payload: u = payload['usage'] for k in ['input_tokens', 'output_tokens', 'cache_read_input_tokens', 'cache_creation_input_tokens', 'total_tokens']: @@ -2014,7 +2032,7 @@ class AppController: 'output': u.get('output_tokens', 0) or 0, 'model': entry.get('model', 'unknown') }) - + if kind == "history_add": content = payload.get("content", payload.get("text", payload.get("message", ""))) content = _resolve_log_ref(content, session_dir) @@ -2045,7 +2063,8 @@ class AppController: content += f"\n\n[TOOL CALLS]\n{tc_str}" else: content = f"[TOOL CALLS]\n{tc_str}" - except: + except (TypeError, ValueError) as e: + logging.getLogger(__name__).debug("tool_calls json serialization failed: %s", e, extra={"source": "app_controller.cb_load_prior_log.tool_calls"}) if content: content += f"\n\n[TOOL CALLS PRESENT]" else: @@ -2067,9 +2086,15 @@ class AppController: }) except json.JSONDecodeError: continue - except Exception as e: + except (OSError, IOError, json.JSONDecodeError, ValueError, TypeError, KeyError, AttributeError) as e: + logging.getLogger(__name__).debug("log load error: %s", e, extra={"source": "app_controller.cb_load_prior_log"}) self.ai_status = f"log load error: {e}" - return + return Result(data=None, errors=[ErrorInfo( + kind=ErrorKind.INTERNAL, + message=str(e), + source="app_controller.cb_load_prior_log", + original=e, + )]) self.session_usage = new_usage self.mma_tier_usage = new_mma_usage @@ -2080,7 +2105,8 @@ class AppController: first_ts = new_token_history[0]['time'] dt = datetime.datetime.strptime(first_ts, '%Y-%m-%dT%H:%M:%S') self._session_start_time = dt.timestamp() - except: + except (ValueError, TypeError, KeyError, IndexError) as e: + logging.getLogger(__name__).debug("token_history first_ts parse failed: %s", e, extra={"source": "app_controller.cb_load_prior_log.token_history"}) self._session_start_time = time.time() self.prior_session_entries = entries self.prior_disc_entries = disc_entries