Skip to content

Commit fbe78a4

Browse files
committed
Add exception handling to stack inspection code for robustness
- Wrap stack inspection loops in try-except blocks in _ExceptionSuggestor.py and ExceptionSuggestor.py to prevent errors from propagating during attribute suggestion - Add try-except block in logging_utils.py around stack inspection to avoid failures determining log source depth - Preserve original logic and fallback behavior while improving stability against unexpected inspection errors
1 parent 1f5ab81 commit fbe78a4

3 files changed

Lines changed: 38 additions & 31 deletions

File tree

WrenchCL/Exceptions/ExceptionSuggestor.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,18 @@ def _suggest_for_exception(
147147

148148
source_obj = obj_match.group(1) if obj_match else None
149149
missing_attr = key_match.group(1)
150-
151-
for frame in reversed(inspect.stack()[:frame_depth]):
152-
for var in frame.frame.f_locals.values():
153-
if not hasattr(var, "__class__"):
154-
continue
155-
if var.__class__.__name__ == source_obj:
156-
keys = [k for k in dir(var) if not k.startswith("__")]
157-
matches = get_close_matches(missing_attr, keys, n=n_suggestions, cutoff=cutoff)
158-
if matches:
159-
return f"{error_msg}\n Did you mean: {', '.join(matches)}?\n"
150+
try:
151+
for frame in reversed(inspect.stack()[:frame_depth]):
152+
for var in frame.frame.f_locals.values():
153+
if not hasattr(var, "__class__"):
154+
continue
155+
if var.__class__.__name__ == source_obj:
156+
keys = [k for k in dir(var) if not k.startswith("__")]
157+
matches = get_close_matches(missing_attr, keys, n=n_suggestions, cutoff=cutoff)
158+
if matches:
159+
return f"{error_msg}\n Did you mean: {', '.join(matches)}?\n"
160+
except Exception:
161+
pass
160162
return error_msg
161163

162164
@classmethod

WrenchCL/_Internal/Logging/logging_utils.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,20 @@ def ensure_str(val: bytes | str) -> Any:
4040

4141
def get_depth(internal=False) -> int:
4242
"""Get stack depth to determine log source."""
43-
for i, frame in enumerate(inspect.stack()):
44-
if (
45-
frame.filename.endswith("cLogger.py")
46-
or "WrenchCL" in frame.filename
47-
or frame.filename == "<string>"
48-
):
49-
if internal:
50-
return i + 2
51-
else:
52-
continue
53-
return i
43+
try:
44+
for i, frame in enumerate(inspect.stack()):
45+
if (
46+
frame.filename.endswith("cLogger.py")
47+
or "WrenchCL" in frame.filename
48+
or frame.filename == "<string>"
49+
):
50+
if internal:
51+
return i + 2
52+
else:
53+
continue
54+
return i
55+
except Exception:
56+
pass
5457
# Fallback: If stack inspection fails, return depth 1 (assume direct caller).
5558
return 1
5659

WrenchCL/_Internal/_ExceptionSuggestor.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,16 @@ def suggest_similar(
2929

3030
source_obj = obj_match.group(1) if obj_match else None
3131
missing_attr = key_match.group(1)
32-
33-
for frame in reversed(inspect.stack()[:frame_depth]):
34-
for var in frame.frame.f_locals.values():
35-
if not hasattr(var, "__class__"):
36-
continue
37-
if var.__class__.__name__ == source_obj:
38-
keys = [k for k in dir(var) if not k.startswith("__")]
39-
matches = get_close_matches(missing_attr, keys, n=n_suggestions, cutoff=cutoff)
40-
if matches:
41-
return f"{error_msg}\n Did you mean: {', '.join(matches)}?\n"
32+
try:
33+
for frame in reversed(inspect.stack()[:frame_depth]):
34+
for var in frame.frame.f_locals.values():
35+
if not hasattr(var, "__class__"):
36+
continue
37+
if var.__class__.__name__ == source_obj:
38+
keys = [k for k in dir(var) if not k.startswith("__")]
39+
matches = get_close_matches(missing_attr, keys, n=n_suggestions, cutoff=cutoff)
40+
if matches:
41+
return f"{error_msg}\n Did you mean: {', '.join(matches)}?\n"
42+
except Exception:
43+
pass
4244
return error_msg

0 commit comments

Comments
 (0)