fix: harden response parsing and CLI/MCP input handling - #2
Merged
protego-maxima-fianto-duri merged 1 commit intoJul 28, 2026
Merged
Conversation
Guard several parse and input paths that previously crashed with a raw Python exception or silently produced wrong data: - BackupServer.to_dict() now includes the storage_usage_pct derived metric alongside the two data-reduction metrics, so JSON output matches what the CLI table already shows. - machine workload parsing treats an empty-string progress / processedSuccessCount during a running backup as "not reported" (progress -> 0, count -> None) instead of raising ValueError; a legitimate integer 0 count is still preserved as 0. - the MCP backup-window parser reports a non-numeric hour token with a clear message instead of a raw int() error, and tasks_json rejects a string custom_volumes instead of silently splitting it into single-character volumes. - the CLI relative time filter (--since/--until) reports a malformed value such as "1h30m" as a friendly parameter error instead of an unhandled traceback. - the CLI export download no longer deletes an existing file at the destination path when a download fails; the SDK stages into a .part file and leaves the destination untouched on failure.
protego-maxima-fianto-duri
merged commit Jul 28, 2026
7d4d432
into
synology-apm:main
7 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This hardens five parse/input paths that either crashed with a raw Python exception or silently produced wrong data. Each change is behavior-preserving for well-formed input — the only behavior change is on previously-crashing or previously-buggy malformed paths. All five are covered by targeted tests.
1.
BackupServer.to_dict()omitsstorage_usage_pctBackupServerexposes three derived@propertymetrics —storage_usage_pct,backup_data_reduction_bytes,backup_data_reduction_ratio— butto_dict()only put the latter two in itsextra=dict. Sinceauto_to_dictserializes dataclass fields only,storage_usage_pctwas dropped from the JSON output entirely, even though the CLI table already displays it. Fix: addstorage_usage_pctto the serialized output alongside the two reduction metrics.2. Empty-string progress/count crashes a running-workload parse
In
_parse_workload, aRUNNINGworkload readscache["progress"](PC/PS/VM) orcache["processedSuccessCount"](FS). Both were guarded withis not None, so an empty string""— which the field can carry before the first counter tick — passed the guard and then raisedValueErrorfromint(float(""))/int(""), failing the whole workload list. Fix: treat an empty/absent value as "not reported" (progress → 0,count → None), while preserving a legitimate integer0count as0.3. MCP backup-window /
tasks_jsoninput validation_parse_backup_window: a non-numeric hour token (e.g.mon:a-b) raised a rawint()ValueErrorinstead of a helpful message. Fix: reportBackup window hours must be integers 0-23, got ...._parse_tasks_json: a stringcustom_volumes(e.g."C:") was passed straight totuple(...), char-splitting it into("C", ":")— two bogus single-character volumes. Fix: require a JSON array and reject a string with a clearValueError.4. Malformed relative time filter throws a traceback
parse_time_filterwrapped only the ISO-8601 branch in error handling; the relative-time branches (30m/1h/7d) calledfloat(value[:-1])unguarded, so a value like--since 1h30mproduced an unhandledValueErrortraceback. Fix: route the relative branch through the sametyper.BadParametermessage the ISO branch uses.5. Failed export download deletes an existing destination file
On
OSError, the CLI export download ranunlink(dest_path). But the SDK stages the download into adest_path + ".part"file and onlyos.replaces it into place on success — an existing file atdest_pathis never touched by a failed download. So the CLI cleanup deleted the user's previous good file while the failed download had written nothing todest_path. Fix: remove the CLI unlink;.partcleanup is already the SDK's responsibility.Testing
make testgreen — 3113 unit tests, coverage 98.76%, plus ruff, mypy, MCP coverage, and version-consistency checks. 12 new tests, each red-green verified against the pre-fix code.