Skip to content

Commit 4269aa2

Browse files
Merge pull request #11 from abhishek72850/patch-105-20230901
Improved indexer error handling
2 parents 8688c9a + e67375e commit 4269aa2

File tree

2 files changed

+76
-17
lines changed

2 files changed

+76
-17
lines changed

src/commands/base_indexer.py

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import os
2+
import re
3+
from typing import List, Tuple
24
import sublime
35
from sublime import Window
46
from ..settings import PyRockSettings
@@ -33,35 +35,76 @@ def _get_indexer_script_path(self):
3335
def _is_indexing_needed(self) -> bool:
3436
file_path = os.path.join(PyRockConstants.INDEX_CACHE_DIRECTORY, PyRockConstants.IMPORT_INDEX_FILE_NAME)
3537
return os.path.exists(file_path)
36-
37-
def _run_import_indexer(self, window: Window, indexer_command: str):
38-
process = subprocess.Popen(
39-
indexer_command,
40-
shell=True,
41-
stdout=subprocess.PIPE,
42-
)
4338

39+
def _track_indexer_progress(self, window: Window, process: subprocess.Popen) -> bool:
4440
start_time = time.perf_counter()
45-
41+
script_success: bool = False
42+
log_errors: bool = False
4643
# Progress tracker
4744
for line in iter(process.stdout.readline, ""):
48-
progress = line.decode('utf-8').strip()
45+
output = line.decode('utf-8').strip()
4946
# Kill process after 20 sec
5047
if (time.perf_counter() - start_time) > 20:
51-
logger.warning(f"Indexing stopped due to timeout at {progress}%")
48+
error_reason = f"Indexing stopped due to timeout at {output}%"
49+
logger.warning(error_reason)
50+
self._command_error_evidence.append(error_reason)
5251
process.terminate()
52+
script_success = False
5353
break
54-
logger.debug(f"Indexing imports...{progress}%")
55-
window.status_message(f"Indexing imports...{progress}%")
56-
if "99" in str(line) or progress == "":
54+
55+
if log_errors:
56+
# Collect error generated from script
57+
self._command_error_evidence.append(output)
58+
elif re.match(r"^([1-9]|[1-9][0-9]|100)$", output):
59+
logger.debug(f"Indexing imports...{output}%")
60+
window.status_message(f"Indexing imports...{output}%")
61+
if 95 <= int(output) <= 100:
62+
script_success = True
63+
elif "FAILED_INDEXING" in output:
64+
script_success = False
65+
log_errors = True
66+
67+
if output == "" or output is None:
5768
break
69+
return script_success
70+
71+
def _collect_cmd_error_output(self, process: subprocess.Popen):
72+
# Collect error generated from command
73+
for line in iter(process.stderr.readline, ""):
74+
output = line.decode('utf-8').strip()
75+
if len(output) == 0 or output == "" or output is None:
76+
break
77+
logger.debug(output)
78+
self._command_error_evidence.append(output)
79+
80+
def _run_import_indexer(self, window: Window, indexer_command: str) -> Tuple[bool, str]:
81+
process = subprocess.Popen(
82+
indexer_command,
83+
shell=True,
84+
stdout=subprocess.PIPE,
85+
stderr=subprocess.PIPE,
86+
)
87+
message: str = ""
88+
script_success: bool = self._track_indexer_progress(window, process)
89+
90+
if not script_success:
91+
if len(self._command_error_evidence) > 0:
92+
logger.error("\n".join(self._command_error_evidence))
93+
else:
94+
self._collect_cmd_error_output(process)
95+
message = "\n".join(self._command_error_evidence)
96+
logger.error(message)
97+
98+
return script_success, message
5899

59100
def _run_indexer(self, window: Window, force=False):
60101
if self._is_indexing_needed() and not force:
61102
logger.debug("Indexing not needed")
62103
window.status_message("Indexing not needed")
63104
return
64105

106+
self._command_error_evidence: List[str] = []
107+
65108
self._generate_serialized_settings()
66109

67110
window.set_status_bar_visible(True)
@@ -114,6 +157,10 @@ def _run_indexer(self, window: Window, force=False):
114157
)
115158

116159
logger.debug(f"Import shell command using: {import_command}")
117-
self._run_import_indexer(window, import_command)
160+
success, message = self._run_import_indexer(window, import_command)
161+
logger.debug(f"Indexing result: {success}")
118162

119-
window.status_message("Finished imports...")
163+
if success:
164+
window.status_message("Finished imports...")
165+
else:
166+
sublime.error_message(f"Indexing Failed\n\n{message}")

src/scripts/indexer.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import json
77
from collections import defaultdict
88
import importlib
9+
import traceback
910
from typing import List, Dict, Tuple, Set
1011
from types import FunctionType, ModuleType
1112
import logging
@@ -110,8 +111,8 @@ def _index_sub_module_members(
110111
f"{parent_module_name}.{module_name}",
111112
self.get_module_members(module_obj)
112113
)
113-
114-
def run(self):
114+
115+
def _run(self):
115116
self.parse_serialized_settings()
116117

117118
system_module_name_list: Set[str] = {
@@ -159,5 +160,16 @@ def run(self):
159160

160161
self.save_imports_to_cache()
161162

163+
def run(self):
164+
try:
165+
self._run()
166+
except Exception:
167+
# Send error Flag
168+
print("FAILED_INDEXING", flush=True)
169+
error_details = traceback.format_exc()
170+
logger.debug(f"Indexing failed due to: {error_details}")
171+
# Send error details to plugin
172+
print(error_details, flush=True)
173+
162174
if __name__ == '__main__':
163175
Indexer().run()

0 commit comments

Comments
 (0)