Skip to content

Commit 3411ff7

Browse files
tumfwkmtumf
authored andcommitted
fix(server.py): improve error handling for missing fields in file operations to provide clearer error messages
test(server.py): update tests to check for RuntimeError on missing fields in file operations
1 parent 1c72ffa commit 3411ff7

File tree

2 files changed

+38
-45
lines changed

2 files changed

+38
-45
lines changed

src/mcp_text_editor/server.py

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -175,35 +175,23 @@ async def run_tool(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
175175
return [TextContent(type="text", text=json.dumps(results, indent=2))]
176176

177177
for file_operation in files:
178-
file_path = None
178+
if "path" not in file_operation:
179+
raise RuntimeError("Missing required field: path")
180+
if "file_hash" not in file_operation:
181+
raise RuntimeError("Missing required field: file_hash")
182+
if "patches" not in file_operation:
183+
raise RuntimeError("Missing required field: patches")
184+
179185
try:
180-
try:
181-
file_path = file_operation["path"]
182-
except KeyError as e:
183-
raise RuntimeError(
184-
"Missing required field: path in file operation"
185-
) from e
186-
187-
try:
188-
file_hash = file_operation["file_hash"]
189-
except KeyError as e:
190-
raise RuntimeError(
191-
f"Missing required field: file_hash for file {file_path}"
192-
) from e
193-
194-
# Ensure patches list is not empty
195-
try:
196-
patches = file_operation["patches"]
197-
except KeyError as e:
198-
raise RuntimeError(
199-
f"Missing required field: patches for file {file_path}"
200-
) from e
186+
file_path = file_operation["path"]
187+
file_hash = file_operation["file_hash"]
188+
patches = file_operation["patches"]
201189

202190
if not patches:
203191
results[file_path] = {
204192
"result": "error",
205193
"reason": "Empty patches list",
206-
"file_hash": None,
194+
"file_hash": file_hash,
207195
"content": None,
208196
}
209197
continue
@@ -214,15 +202,22 @@ async def run_tool(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
214202
)
215203
results[file_path] = result
216204
except Exception as e:
217-
if file_path:
218-
results[file_path] = {
219-
"result": "error",
220-
"reason": str(e),
221-
"file_hash": None,
222-
"content": None,
223-
}
224-
else:
225-
raise
205+
current_hash = None
206+
if "path" in file_operation:
207+
file_path = file_operation["path"]
208+
try:
209+
current_content, _, _, current_hash, _, _ = (
210+
await self.editor.read_file_contents(file_path)
211+
)
212+
except Exception:
213+
current_hash = None
214+
215+
results[file_path if "path" in file_operation else "unknown"] = {
216+
"result": "error",
217+
"reason": str(e),
218+
"file_hash": current_hash,
219+
"content": None,
220+
}
226221

227222
return [TextContent(type="text", text=json.dumps(results, indent=2))]
228223
except Exception as e:

tests/test_server.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,13 @@ async def test_edit_contents_handler_malformed_input():
310310
@pytest.mark.asyncio
311311
async def test_edit_contents_handler_empty_patches():
312312
"""Test EditTextFileContents handler with empty patches."""
313-
edit_args = {"files": [{"path": "test.txt", "hash": "any_hash", "patches": []}]}
313+
edit_args = {
314+
"files": [{"path": "test.txt", "file_hash": "any_hash", "patches": []}]
315+
}
314316
result = await edit_contents_handler.run_tool(edit_args)
315317
edit_results = json.loads(result[0].text)
316318
assert edit_results["test.txt"]["result"] == "error"
317-
assert edit_results["test.txt"]["file_hash"] is None
318-
edit_results = json.loads(result[0].text)
319-
assert edit_results["test.txt"]["result"] == "error"
320-
assert edit_results["test.txt"]["file_hash"] is None
319+
assert edit_results["test.txt"]["reason"] == "Empty patches list"
321320

322321

323322
@pytest.mark.asyncio
@@ -361,10 +360,10 @@ async def test_edit_contents_handler_missing_hash(tmp_path):
361360
]
362361
}
363362

364-
result = await edit_contents_handler.run_tool(edit_args)
365-
edit_results = json.loads(result[0].text)
366-
assert edit_results[str(test_file)]["result"] == "error"
367-
assert "Missing required field: file_hash" in edit_results[str(test_file)]["reason"]
363+
# file_hashが欠けている場合は例外が発生することを確認
364+
with pytest.raises(RuntimeError) as exc_info:
365+
await edit_contents_handler.run_tool(edit_args)
366+
assert "Missing required field: file_hash" in str(exc_info.value)
368367

369368

370369
@pytest.mark.asyncio
@@ -402,7 +401,6 @@ async def test_edit_contents_handler_missing_patches():
402401
"""Test EditTextFileContents handler with missing patches field."""
403402
edit_args = {"files": [{"path": "test.txt", "file_hash": "any_hash"}]}
404403

405-
result = await edit_contents_handler.run_tool(edit_args)
406-
edit_results = json.loads(result[0].text)
407-
assert edit_results["test.txt"]["result"] == "error"
408-
assert "Missing required field: patches" in edit_results["test.txt"]["reason"]
404+
with pytest.raises(RuntimeError) as exc_info:
405+
await edit_contents_handler.run_tool(edit_args)
406+
assert "Missing required field: patches" in str(exc_info.value)

0 commit comments

Comments
 (0)