Add param/value to five error_response() call sites (F17)#31
Add param/value to five error_response() call sites (F17)#31cmeans-claude-dev[bot] merged 1 commit intomainfrom
Conversation
Call sites that emit a structured error envelope but previously omitted the `param`/`value` fields that smart clients use to dispatch on which argument triggered the failure: - modules/filestation/metadata.py:76 (multi-path get_info empty result: param="paths", value=paths) - modules/filestation/metadata.py:222 (get_dir_size timeout: param="timeout", value=timeout) - modules/filestation/operations.py:245 (copy/move timeout: param="timeout", value=timeout) - modules/filestation/operations.py:353 (delete timeout: param="timeout", value=timeout) - modules/filestation/transfer.py:209 (download local-write OSError: param="dest_folder", value=dest_folder) Human-readable `message` text is unchanged — this is purely additive on the envelope. Existing tests at the matching regression points grow a `param`/`value` assertion pair. Out of scope: operations.py:258/367 (bare DSM_ERROR on background-task failures) — tracked separately as issue #30 because it changes error- response semantics rather than adding metadata. Closes #29. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
cmeans
left a comment
There was a problem hiding this comment.
QA Review — PR #31
Verification (this session, on pr-31 HEAD e333c0f)
| Check | Result |
|---|---|
uv run pytest (full suite) |
495 passed, 94 deselected (integration + vdsm markers, excluded by addopts; vdsm runs in .github/workflows/vdsm.yml — green on this PR), coverage 96.03% |
Targeted: test_empty_files_list_returns_not_found, test_dir_size_timeout, test_copy_timeout, test_delete_timeout, test_download_write_permission_error |
5/5 PASSED — each exercises the param/value fields added at its paired source site |
uv run ruff check . |
All checks passed |
uv run mypy src |
Success: no issues found in 27 source files |
| CI on PR | lint, typecheck, test (3.11/3.12/3.13), version-sync, validate-server-json, vdsm integration tests — all green |
Scope vs issue #29
| AC | Status |
|---|---|
Audit all error_response() calls in modules/filestation/*.py and add param/value where applicable |
Complete — full census below |
| Existing tests continue to pass (envelope changes are additive) | 495/495 green |
| Regression assertions for at least one site per file | Exceeded — 5 regressions across 3 files (2 in metadata, 2 in operations, 1 in transfer) |
No changes to human-readable message text |
Verified — diff adds only param=/value= lines; no message string touched |
CHANGELOG ## Unreleased → ### Changed entry |
Present, accurate, and correctly under ### Changed (not ### Added) |
Audit census
Grepped every error_response( call in src/mcp_synology/modules/filestation/*.py and classified:
Modified (5):
metadata.py:75NOT_FOUNDempty-result →param="paths",value=pathsmetadata.py:222TIMEOUTget_dir_size →param="timeout",value=timeoutoperations.py:243TIMEOUTcopy/move →param="timeout",value=timeoutoperations.py:351TIMEOUTdelete →param="timeout",value=timeouttransfer.py:207FILESYSTEM_ERRORdownload write OSError →param="dest_folder",value=dest_folder
Already had param/value (confirmed by reading the file) — correctly left untouched:
operations.py:94renamenew_nameis a path →param="new_name"transfer.py:44upload local not-found →param="local_path"transfer.py:71upload already-exists →param="filename"transfer.py:82upload read OSError →param="local_path"transfer.py:120download dest not-found →param="dest_folder"transfer.py:134download dest exists →param="dest_folder"
Deliberately out of scope:
transfer.py:162/transfer.py:201disk-full preflight + ENOSPC: PR body correctly reasons that thedisk_fullcode itself is the dispatch signal; the state being measured (free space vs file size) isn't a direct arg fault. Defensible judgment call.operations.py:257/operations.py:365bareDSM_ERRORin background-task failure paths: explicitly deferred to F18 / issue #30, where the desired change is routingerr_codethrougherror_from_code()(a behavior change, not a metadata addition). Correct scope boundary.
Code notes
value=pathsatmetadata.py:80passes the list through.error_response()typesvalue: Any | None, so list values serialize cleanly — verified by the regression assertionbody["error"]["value"] == ["/video/missing1", "/video/missing2"].value=timeoutpasses a float; regression asserts... == 1.0— clean JSON roundtrip.- All new fields use the raw input arg (
paths,timeout,dest_folder) rather than a normalized/derived form, which is the right choice for client dispatch (clients want to key off what they sent).
Findings
None. Applying Ready for QA Signoff.
|
QA audit — applying Verification in this session on
Independent audit of every |
Summary
Closes #29. Pure envelope metadata addition — no behavior change, no message text change.
Five
error_response()call sites inmodules/filestation/*.pypreviously emitted envelopes without theparam/valuefields that smart clients use to dispatch on which argument triggered the failure. Adding them makes the envelopes self-describing (client can re-prompt specifically for the offending path, or log the timeout value, without parsing the human-readablemessage).Changes
src/mcp_synology/modules/filestation/metadata.py:76NOT_FOUND(multi-pathget_infoempty result)param="paths",value=pathssrc/mcp_synology/modules/filestation/metadata.py:222TIMEOUT(get_dir_sizetimeout)param="timeout",value=timeoutsrc/mcp_synology/modules/filestation/operations.py:245TIMEOUT(copy/move timeout)param="timeout",value=timeoutsrc/mcp_synology/modules/filestation/operations.py:353TIMEOUT(delete timeout)param="timeout",value=timeoutsrc/mcp_synology/modules/filestation/transfer.py:209FILESYSTEM_ERROR(download local-write OSError fallthrough)param="dest_folder",value=dest_folderFive matching regression assertions added to existing tests:
test_empty_files_list_returns_not_found(test_metadata.py)test_dir_size_timeout(test_metadata.py)test_copy_timeout(test_operations.py)test_delete_timeout(test_operations.py)test_download_write_permission_error(test_transfer.py)Scope notes
Why these specific sites
Audited every
error_response(call insrc/mcp_synology/modules/filestation/*.py. Sites already carryingparam/valuewere untouched (operations.py:94rename-rejects-path,transfer.py:44,71,82,120,134,162,201upload/download pre-flight checks). Sites where no concrete argument is meaningfully at fault (transfer.py:162disk-full preflight — a calculation, not an arg;transfer.py:201ENOSPC — same) were left alone.Explicitly out of scope
operations.py:258and:367— bareDSM_ERRORon background-task failures. These are F18 / issue Route task-failure error codes through error_from_code() for specific envelopes #30, because the desired change there is to routeerr_codethrougherror_from_code()for a more specific envelope code. That's a behavior change, not a metadata addition, and QA explicitly wanted it reviewed separately.modules/filestation/*.py(e.g.,modules/system/*.py). Issue Add param/value to error_response() call sites for structured client dispatch #29 scoped the audit to filestation.Test plan
Automated (CI)
uv run ruff check src/ tests/— cleanuv run mypy src/— clean (no type changes)uv run pytest— 495 passed, 96.03% coverage (no new tests, five regressions tightened)validate-server-jsonon CI should remain green (no workflow changes)Manual
None required — this is a structured-response metadata change verified by the automated assertions.
🤖 Generated with Claude Code