From 4bf655236d4c36b471546a65714e4c6b784dc081 Mon Sep 17 00:00:00 2001 From: Marcus van Elst Date: Tue, 14 Apr 2026 13:19:32 +0200 Subject: [PATCH] fix: treat DSM 599 as task-not-ready in _poll_task, poll until 60s timeout DirSize/MD5 return error 599 while the async task is still initialising on the NAS, not only after the task is gone. Remove the 5-consecutive-599 abort limit and the debug stderr logging; instead pass on 599 and keep polling until the existing 60 s timeout fires. Rename the test that checked the old limit to reflect the new timeout-based behaviour. Co-Authored-By: Claude Sonnet 4.6 --- pyproject.toml | 2 +- src/mcp_synology_filestation/__init__.py | 2 +- .../tools/filestation.py | 31 +++---------------- tests/test_tools_filestation.py | 5 +-- uv.lock | 2 +- 5 files changed, 10 insertions(+), 32 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7b0d8e9..846165c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mcp-synology-filestation" -version = "0.2.3" +version = "0.2.4" description = "MCP server for Synology FileStation" requires-python = ">=3.12" dependencies = [ diff --git a/src/mcp_synology_filestation/__init__.py b/src/mcp_synology_filestation/__init__.py index 8aad4b5..4646ba6 100644 --- a/src/mcp_synology_filestation/__init__.py +++ b/src/mcp_synology_filestation/__init__.py @@ -1,3 +1,3 @@ """MCP server for Synology FileStation.""" -__version__ = "0.2.3" +__version__ = "0.2.4" diff --git a/src/mcp_synology_filestation/tools/filestation.py b/src/mcp_synology_filestation/tools/filestation.py index 1005b28..aab94b1 100644 --- a/src/mcp_synology_filestation/tools/filestation.py +++ b/src/mcp_synology_filestation/tools/filestation.py @@ -81,26 +81,16 @@ def register_filestation( ``(True, status_dict)`` on success, or ``(False, "Error: …")`` on DSM error or timeout. """ - import sys as _sys - from mcp_synology_filestation.client import SynologyError as _SynologyError delay = 0.2 elapsed = initial_delay timeout = 60.0 - consecutive_599 = 0 - attempt = 0 - - _sys.stderr.write( - f"[poll] START {api}/status v{version} taskid={taskid} initial_delay={initial_delay}\n" - ) - _sys.stderr.flush() if initial_delay > 0: await asyncio.sleep(initial_delay) while True: - attempt += 1 try: status_data = await client.request( api, @@ -108,25 +98,12 @@ def register_filestation( version=version, params={"taskid": taskid}, ) - consecutive_599 = 0 - finished = status_data.get("finished") - _sys.stderr.write( - f"[poll] #{attempt} elapsed={elapsed:.2f}s finished={finished}" - f" data_keys={list(status_data.keys())}\n" - ) - _sys.stderr.flush() except _SynologyError as e: - _sys.stderr.write( - f"[poll] #{attempt} elapsed={elapsed:.2f}s" - f" SynologyError code={e.code} msg={e}\n" - ) - _sys.stderr.flush() if e.code == 599: - # 599 can be transient (task just started, not yet available). - # Retry up to 5 times before giving up. - consecutive_599 += 1 - if consecutive_599 >= 5: - return False, f"Error: {e}" + # DSM returns 599 while the async task is still initialising + # or running (task-not-yet-available). Treat it the same as + # finished=False and keep polling until the 60 s timeout. + pass else: return False, f"Error: {e}" else: diff --git a/tests/test_tools_filestation.py b/tests/test_tools_filestation.py index affe958..c88e355 100644 --- a/tests/test_tools_filestation.py +++ b/tests/test_tools_filestation.py @@ -1635,8 +1635,8 @@ async def test_dir_size_retries_on_transient_599(config: AppConfig) -> None: @pytest.mark.asyncio -async def test_dir_size_fails_after_5_consecutive_599(config: AppConfig) -> None: - """dir_size gives up and returns Error: after 5 consecutive 599 responses.""" +async def test_dir_size_times_out_on_persistent_599(config: AppConfig) -> None: + """dir_size returns Error: after 60 s timeout when DSM keeps returning 599.""" client = MagicMock() async def _request(api, method, version=None, params=None, **kwargs): @@ -1651,6 +1651,7 @@ async def test_dir_size_fails_after_5_consecutive_599(config: AppConfig) -> None result = await tools["dir_size"](path="/dead") assert result.startswith("Error:") + assert "timed out" in result.lower() or "60 seconds" in result # ────────────────────────────────────────────────────────────────────────── diff --git a/uv.lock b/uv.lock index 7df7243..058a4a7 100644 --- a/uv.lock +++ b/uv.lock @@ -362,7 +362,7 @@ wheels = [ [[package]] name = "mcp-synology-filestation" -version = "0.2.0" +version = "0.2.4" source = { editable = "." } dependencies = [ { name = "click" },