Repository navigation
fix(core): report rejected client data as ActiveSync Status 6 - #248
Open
TDannhauer wants to merge 1 commit into
Open
TDannhauer wants to merge 1 commit into
TDannhauer wants to merge 1 commit into
Conversation
Horde_Core_ActiveSync_Driver::changeMessage() returned false for every backend exception, which the importer reports as Status 5 (server error). Clients treat Status 5 as transient and resend the same item on every Sync, forever, even when the backend will never accept it. Map exceptions implementing Horde\Exception\InvalidDataThrowable (e.g. Turba_Exception_InvalidAttribute for a value over its configured maxlength) to ['error' => STATUS_INVALID] and log them as a warning naming the item; all other failures keep returning false and are logged as errors. The eight identical catch blocks are folded into _importFailure(). Requires the matching horde/ActiveSync change that lets the importer honour a backend-supplied status. Part of horde/turba#73.
This was referenced Oct 26, 2026
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.
Summary
Horde_Core_ActiveSync_Driver::changeMessage()returns['error' => Horde_ActiveSync_Request_Sync::STATUS_INVALID]when the backend rejected the client's data (exception implementingHorde\Exception\InvalidDataThrowable), and keeps returningfalsefor every other failure.catch (Horde_Exception $e)blocks inchangeMessage()are folded into one_importFailure()helper.Part of horde/turba#73.
Motivation
Every
changeMessage()failure was reported to the device asStatus 5(server error). Clients treat that as transient and resend the item on the next Sync — forever, when the backend will never accept the data (a Turba attribute over its configuredmaxlength, for example).Status 6(STATUS_INVALID) tells the client to drop the change.Changes
lib/Horde/Core/ActiveSync/Driver.phpuse Horde\Exception\InvalidDataThrowable;changeMessage(): eachcatch (Horde_Exception $e)now doesreturn $this->_importFailure($e, $folderid, $id);(previously_endBuffer(); return false;plus anerrlog). Docblock documents the new return shape._importFailure(Horde_Exception $e, $folderid, $id): ends output buffering;InvalidDataThrowable→warn("Rejected client change for %s in folder %s: %s") and['error' => STATUS_INVALID]; anything else →err($e->getMessage())andfalse, as before.test/Unit/ActiveSync/DriverChangeMessageStatusTest.php(new): contact replace and contact import with anInvalidDataThrowable→STATUS_INVALID; plainHorde_Exception→false.Exceptions
The caught type is unchanged (
Horde_Exception, the ceiling in this legacy class). The handler only classifies it: anInvalidDataThrowableis an expected, tolerable condition caused by the client (logged atwarn, item rejected with a status the client understands); anything else is still a server-side failure (logged aterr, retryableStatus 5). No exception is swallowed that was not swallowed before.Dependencies
InvalidDataThrowablefrom feat(exception): add InvalidDataThrowable marker interface Exception#6. Without it theinstanceofcheck is simply never true and the old behaviour remains.Connector_Importermust honour['error' => …]; with the current importer the array is truthy and treated as a stat array, so this PR should be merged after the ActiveSync one (or together).Test plan
DriverChangeMessageStatusTest(3 tests)test/Unit/ActiveSyncsuite: only the pre-existing failures inDriverMeetingResponseTest/DriverVersionCallbackTest(reproduced on pristineFRAMEWORK_6_0), nothing newStatus 6, device stops resending