Skip to content

feat(activesync): let backends set the per-item status of a failed change - #111

Merged
ralflang merged 1 commit into
FRAMEWORK_6_0from
feat/backend-item-status
Nov 2, 2026
Merged

ralflang merged 1 commit into
FRAMEWORK_6_0from
feat/backend-item-status

Conversation

@TDannhauer

@TDannhauer TDannhauer commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Horde_ActiveSync_Driver_Base::changeMessage() may now return ['error' => <Sync status>] in addition to a stat array or false.
  • Horde_ActiveSync_Connector_Importer::importMessageChange() propagates that status into the per-item failure list instead of always reporting Status 5.

Part of horde/turba#73 (follow-up to #110, which stopped the same failure from aborting the whole Sync request).

Motivation

When a backend cannot store a client change because the data is invalid (a contact field over its configured length, for example), the importer reported Status 5 (server error). Clients treat Status 5 as transient and resend the item on every Sync. Status 6 (STATUS_INVALID) tells the client to drop the change — but the driver API had no way to say which one applies.

Changes

  • lib/Horde/ActiveSync/Driver/Base.php: changeMessage() docblock documents the return contract — stat array on success, false for a server error (retryable, Status 5), ['error' => STATUS_*] for a backend-chosen status (STATUS_INVALID for rejected data).
  • lib/Horde/ActiveSync/Connector/Importer.php
    • main path: if (!$stat || !empty($stat['error'])) → status from $stat['error'], default STATUS_SERVERERROR; log line includes the status; return [0 => $id ?: false, 'error' => $status] as before.
    • task duplicate-addition path: && empty($stat['error']) so an error array is not mistaken for a stat array.
  • doc/architecture.md: one paragraph on the per-item status in the importer section.
  • test/unit/Horde/ActiveSync/Connector/ImporterChangeStatusTest.php (new, 4 tests): false → STATUS_SERVERERROR; ['error' => STATUS_INVALID] → STATUS_INVALID for ADD and MODIFY; stat array → success and change map updated.

Compatibility

Existing drivers that return a stat array or false are unaffected. Request/Sync.php already encodes importfailures[$id] per item, so no change there.

Dependencies

Test plan

…ange

Connector_Importer::importMessageChange() reported every changeMessage()
failure as Status 5 (server error), so a client resends an item the
server will never accept on every Sync.

Allow Driver_Base::changeMessage() to return ['error' => <Status>] in
addition to false; the importer propagates the status into the
importfailures list and still defaults to Status 5 for false. The core
driver uses this to answer Status 6 (STATUS_INVALID) when the backend
rejected the client's data (see horde/turba#73).
@github-actions

Copy link
Copy Markdown

🔍 CI Results

Overall: ❌ 12/12 lanes failed

TL;DR: ❌ Quality issues: PHP-CS-Fixer: 47 files.

Summary by PHP Version

PHP dev stable
8.1 ❌ ❌
8.2 ❌ ❌
8.3 ❌ ❌
8.4 ❌ ❌
8.5 ❌ ❌
8.6 ❌ ❌

Quality Metrics

  • PHPUnit: did not run (12 lanes exited non-zero with no test output) ❌
  • PHPStan: No errors found ✅ — 8 advisories at level 2
  • PHP-CS-Fixer: 47 unique files with issues (of 233 checked) ⚠️
❌ Failed Lanes

php8.1-dev

  • PHPUnit: 0 failures, 0 errors

php8.1-stable

  • PHPUnit: 0 failures, 0 errors

php8.2-dev

  • PHPUnit: 0 failures, 0 errors

php8.2-stable

  • PHPUnit: 0 failures, 0 errors

php8.3-dev

  • PHPUnit: 0 failures, 0 errors

php8.3-stable

  • PHPUnit: 0 failures, 0 errors

php8.4-dev

  • PHPUnit: 0 failures, 0 errors
  • PHP-CS-Fixer: 47 files with issues

php8.4-stable

  • PHPUnit: 0 failures, 0 errors

php8.5-dev

  • PHPUnit: 0 failures, 0 errors

php8.5-stable

  • PHPUnit: 0 failures, 0 errors

php8.6-dev

  • PHPUnit: 0 failures, 0 errors

php8.6-stable

  • PHPUnit: 0 failures, 0 errors

CI powered by horde-components • View full results

@ralflang
ralflang merged commit d363cd5 into FRAMEWORK_6_0 Nov 2, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants