Skip to content

Commit af2fd94

Browse files
committed
fix: resolve merge conflicts; apply review feedback on logging
1 parent 2cc885f commit af2fd94

7 files changed

Lines changed: 57 additions & 66 deletions

File tree

api/logs.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from flask import Blueprint, jsonify
1515

1616
from utils.workspace_path import resolve_workspace_path
17-
from utils.path_helpers import to_epoch_ms
17+
from utils.path_helpers import to_epoch_ms, warn_workspace_json_read
1818

1919
bp = Blueprint("logs", __name__)
2020
_logger = logging.getLogger(__name__)
@@ -95,11 +95,7 @@ def get_logs():
9595
wd = json.load(f)
9696
workspace_folder = wd.get("folder")
9797
except Exception as e:
98-
_logger.warning(
99-
"Failed to read workspace.json for %s: %s",
100-
name,
101-
e,
102-
)
98+
warn_workspace_json_read(_logger, name, e)
10399

104100
try:
105101
# closing() guarantees .close() on scope exit (issue #17).

api/search.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from utils.exclusion_rules import build_searchable_text, is_excluded_by_rules
1818
from utils.workspace_path import resolve_workspace_path, get_cli_chats_path
19-
from utils.path_helpers import to_epoch_ms
19+
from utils.path_helpers import to_epoch_ms, warn_workspace_json_read
2020
from utils.text_extract import extract_text_from_bubble
2121
from utils.cli_chat_reader import list_cli_projects, traverse_blobs, messages_to_bubbles
2222
from models import Bubble, Composer, SchemaError
@@ -115,11 +115,7 @@ def search():
115115
if fn:
116116
ws_id_to_name[name] = _url_unquote(fn)
117117
except Exception as e:
118-
_logger.warning(
119-
"Failed to read workspace.json for %s: %s",
120-
name,
121-
e,
122-
)
118+
warn_workspace_json_read(_logger, name, e)
123119
except Exception as e:
124120
_logger.warning(
125121
"Failed to list workspace entries under %s: %s",
@@ -305,11 +301,7 @@ def search():
305301
wd = json.load(f)
306302
workspace_folder = wd.get("folder")
307303
except Exception as e:
308-
_logger.warning(
309-
"Failed to read workspace.json for %s: %s",
310-
name,
311-
e,
312-
)
304+
warn_workspace_json_read(_logger, name, e)
313305
workspace_name = _workspace_display_name_from_folder(workspace_folder, fallback=name)
314306

315307
# try/finally guarantees .close() on every exit path (issue #17).

api/workspaces.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515

1616
from utils.workspace_path import resolve_workspace_path, get_cli_chats_path
1717
from utils.cli_chat_reader import list_cli_projects
18-
from utils.path_helpers import get_workspace_folder_paths, get_workspace_display_name
18+
from utils.path_helpers import (
19+
get_workspace_folder_paths,
20+
get_workspace_display_name,
21+
warn_workspace_json_read,
22+
)
1923
from utils.workspace_descriptor import read_json_file
2024
from services.workspace_resolver import (
2125
_infer_workspace_name_from_context,
@@ -118,11 +122,7 @@ def get_workspace(workspace_id):
118122
if inferred:
119123
workspace_name = inferred
120124
except Exception as e:
121-
_logger.warning(
122-
"Failed to read workspace.json for %s: %s",
123-
workspace_id,
124-
e,
125-
)
125+
warn_workspace_json_read(_logger, workspace_id, e)
126126
inferred = _infer_workspace_name_from_context(workspace_path, workspace_id)
127127
if inferred:
128128
workspace_name = inferred

services/workspace_listing.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
get_workspace_folder_paths,
1515
normalize_file_path,
1616
to_epoch_ms,
17+
warn_workspace_json_read,
1718
)
1819
from utils.workspace_descriptor import read_json_file
1920
from utils.workspace_path import get_cli_chats_path
@@ -133,8 +134,8 @@ def _safe_fetchall(query: str, params: tuple = ()) -> list:
133134
cid,
134135
e,
135136
)
136-
except Exception as e:
137-
_logger.error("Failed to load composer rows from global storage: %s", e)
137+
except Exception:
138+
_logger.exception("Failed to load composer rows from global storage")
138139

139140
# Group workspace entries by normalized folder path
140141
folder_to_entries: dict[str, list] = {}
@@ -148,11 +149,7 @@ def _safe_fetchall(query: str, params: tuple = ()) -> list:
148149
if first_folder:
149150
norm_folder = normalize_file_path(first_folder)
150151
except Exception as e:
151-
_logger.warning(
152-
"Failed to read workspace.json for %s: %s",
153-
entry["name"],
154-
e,
155-
)
152+
warn_workspace_json_read(_logger, entry["name"], e)
156153
if not norm_folder:
157154
norm_folder = entry["name"] # fallback to workspace ID
158155
entry_folder_map[entry["name"]] = norm_folder

services/workspace_resolver.py

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
get_workspace_display_name,
1616
get_workspace_folder_paths,
1717
normalize_file_path,
18+
warn_workspace_json_read,
1819
)
1920
from utils.workspace_descriptor import basename_from_pathish, read_json_file
2021
from services.workspace_db import _open_global_db
@@ -139,11 +140,7 @@ def _get_project_from_file_path(
139140
best_len = len(wp)
140141
best_match = entry["name"]
141142
except Exception as e:
142-
_logger.warning(
143-
"Failed to read workspace.json for %s: %s",
144-
entry["name"],
145-
e,
146-
)
143+
warn_workspace_json_read(_logger, entry["name"], e)
147144
return best_match
148145

149146

@@ -159,11 +156,7 @@ def _create_project_name_to_workspace_id_map(workspace_entries):
159156
if folder_name:
160157
mapping[folder_name] = entry["name"]
161158
except Exception as e:
162-
_logger.warning(
163-
"Failed to read workspace.json for %s: %s",
164-
entry["name"],
165-
e,
166-
)
159+
warn_workspace_json_read(_logger, entry["name"], e)
167160
return mapping
168161

169162

@@ -176,11 +169,7 @@ def _create_workspace_path_to_id_map(workspace_entries):
176169
normalized = normalize_file_path(folder)
177170
out[normalized] = entry["name"]
178171
except Exception as e:
179-
_logger.warning(
180-
"Failed to read workspace.json for %s: %s",
181-
entry["name"],
182-
e,
183-
)
172+
warn_workspace_json_read(_logger, entry["name"], e)
184173
return out
185174

186175

@@ -294,11 +283,7 @@ def _determine_project_for_conversation(
294283
if name:
295284
folder_name_to_ws.append({"name": name, "id": entry["name"]})
296285
except Exception as e:
297-
_logger.warning(
298-
"Failed to read workspace.json for %s: %s",
299-
entry["name"],
300-
e,
301-
)
286+
warn_workspace_json_read(_logger, entry["name"], e)
302287

303288
best_id = None
304289
best_len = 0

services/workspace_tabs.py

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
get_workspace_folder_paths,
1414
normalize_file_path,
1515
to_epoch_ms,
16+
warn_workspace_json_read,
1617
)
1718
from utils.exclusion_rules import build_searchable_text, is_excluded_by_rules
1819
from utils.text_extract import extract_text_from_bubble
@@ -46,6 +47,19 @@ def _try_loads_kv_value(raw: str | None) -> Any | None:
4647
return None
4748

4849

50+
_KV_VALUE_LOG_LIMIT = 200
51+
52+
53+
def _kv_value_log_preview(value: object | None, limit: int = _KV_VALUE_LOG_LIMIT) -> str:
54+
"""Truncated KV payload for warning logs (avoids multi-MB log lines on bad rows)."""
55+
if value is None:
56+
return "None"
57+
text = value if isinstance(value, str) else str(value)
58+
if len(text) > limit:
59+
return text[:limit] + "..."
60+
return text
61+
62+
4963
def assemble_workspace_tabs(
5064
workspace_id: str,
5165
workspace_path: str,
@@ -73,11 +87,7 @@ def assemble_workspace_tabs(
7387
if first_folder:
7488
target_folder = normalize_file_path(first_folder)
7589
except Exception as e:
76-
_logger.warning(
77-
"Failed to read workspace.json for %s: %s",
78-
workspace_id,
79-
e,
80-
)
90+
warn_workspace_json_read(_logger, workspace_id, e)
8191
if target_folder:
8292
for entry in workspace_entries:
8393
try:
@@ -87,11 +97,7 @@ def assemble_workspace_tabs(
8797
if f2 and normalize_file_path(f2) == target_folder:
8898
matching_ws_ids.add(entry["name"])
8999
except Exception as e:
90-
_logger.warning(
91-
"Failed to read workspace.json for %s: %s",
92-
entry["name"],
93-
e,
94-
)
100+
warn_workspace_json_read(_logger, entry["name"], e)
95101

96102
bubble_map: dict[str, dict] = {}
97103
code_block_diff_map: dict[str, list] = {}
@@ -122,12 +128,12 @@ def _safe_fetchall(query: str, params: tuple = ()) -> list:
122128
continue
123129
try:
124130
parsed = json.loads(row["value"])
125-
except json.JSONDecodeError as e:
131+
except (json.JSONDecodeError, TypeError, ValueError) as e:
126132
_logger.warning(
127-
"Failed to decode Bubble from %s: %s (value: %r)",
133+
"Failed to decode Bubble from %s: %s (value_preview=%r)",
128134
row["key"],
129135
e,
130-
row["value"],
136+
_kv_value_log_preview(row["value"]),
131137
)
132138
continue
133139
try:
@@ -206,12 +212,13 @@ def _safe_fetchall(query: str, params: tuple = ()) -> list:
206212
continue
207213
try:
208214
parsed = json.loads(row["value"])
209-
except json.JSONDecodeError as e:
215+
except (json.JSONDecodeError, TypeError, ValueError) as e:
210216
_logger.warning(
211-
"Failed to decode Composer from composerData:%s: %s (value: %r)",
217+
"Failed to decode Composer from composerData:%s: %s (key=%s, value_preview=%r)",
212218
composer_id,
213219
e,
214-
row["value"],
220+
row["key"],
221+
_kv_value_log_preview(row["value"]),
215222
)
216223
continue
217224
try:

utils/path_helpers.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Path utility functions mirroring src/utils/path.ts"""
22

3+
import logging
34
import os
45
import sys
56
from datetime import datetime
@@ -142,3 +143,16 @@ def get_workspace_display_name(workspace_data: dict, fallback: str | None = None
142143
if decoded:
143144
return decoded
144145
return fallback or ""
146+
147+
148+
def warn_workspace_json_read(
149+
logger: logging.Logger,
150+
workspace_id: str,
151+
err: BaseException,
152+
) -> None:
153+
"""Log a standard warning when workspace.json cannot be read (shared across services/api)."""
154+
logger.warning(
155+
"Failed to read workspace.json for %s: %s",
156+
workspace_id,
157+
err,
158+
)

0 commit comments

Comments
 (0)