[9.4] fix(outlook): dispatch Contacts by item type and harden folder/field assumptions (#4147) - #4151
Merged
Merged
Conversation
…assumptions (#4147) Related to elastic/sdh-search#1898 Follow-up to #4123. The last month has been a series of "the next malformed item aborts the whole sync" reports, most recently `'DistributionList' object has no attribute 'email_addresses'`. This PR fixes that class of failure with explicit, visible handling, and audits the connector for the remaining assumptions of the same shape. ## Root cause The Contacts folder returns two item models — `Contact` and `DistributionList` — but the formatter assumed every item was a `Contact` and read per-contact fields off it, so a single contact group aborted the entire sync. The same "unhandled shape aborts everything" gap existed elsewhere: Calendar/Tasks folders that shared and resource mailboxes can legitimately lack, birthday events without a start, and an optional LDAP `type` key. ## Changes **Contacts formatted by item type.** `_fetch_contacts` now dispatches on type: a `Contact` goes through the strict `contact_doc_formatter` and a contact group through a dedicated `distribution_list_doc_formatter` that indexes it by name and its members' email addresses (typed `"Distribution List"`). The folder query fetches the union of both models' fields (incl. `members`). The Contacts folder contractually returns only these two models, so any other type raises a `TypeError` rather than being silently skipped — an unknown type is a broken assumption we want surfaced, not a whole category of items quietly dropped. (Thanks @artem-shelkovnikov for the review — explicit type handling over defensive `getattr`, and failing on unexpected types.) **Note on approach.** An earlier revision of this PR wrapped all formatting in a broad `_format_item` guard that caught item-shape errors (`AttributeError`/`KeyError`/`ValueError`/`TypeError`) and skipped the item. That was dropped: swallowing those errors around every item can turn a systematic bug into a "successful" sync that returns 0 items and deletes previously indexed documents. Instead, known shapes are handled explicitly (type dispatch + targeted field guards) and genuine errors still fail the sync loudly — consistent with the principle established in #4085/#4123. **Remaining assumptions found in the audit, now fixed:** * **Calendar & Tasks folders** are now skipped on `ErrorFolderNotFound`, mirroring the existing Contacts/mail-folder handling. Shared and resource mailboxes can legitimately lack these folders; previously that aborted the sync (same class as #4065). * **Birthdays calendar branch** called `.split("T")` on the formatted datetime, which is `None` when `calendar.start` is missing → `AttributeError`. Now guarded. * **Optional LDAP `type` key** is read with `.get(...)` instead of `user["type"]`. ## Test plan * `pytest tests/sources/test_outlook.py` (65 tests), incl. coverage for: * contact / `DistributionList` type dispatch and the group formatter * unexpected Contacts item type → raises `TypeError` * `ErrorFolderNotFound` skips for Calendar / child calendars / Tasks * birthday without a start * missing LDAP `type` key * `ruff check` / `ruff format --check` --------- Co-authored-by: Cursor <cursoragent@cursor.com>
entsearchmachine
approved these changes
Jul 10, 2026
erikcurrin-elastic
approved these changes
Jul 10, 2026
Jan-Kazlouski-elastic
approved these changes
Jul 10, 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.
Backports the following commits to 9.4: