From 3c09d1de0948680b8efa73d6c7c7eac23fa78a42 Mon Sep 17 00:00:00 2001 From: Kevin Jump Date: Sun, 16 Aug 2026 07:22:53 +0100 Subject: [PATCH] Fix silently discarded save failures in Language/DictionaryItem/Webhook serializers SaveItemAsync discarded the Attempt returned by ILanguageService, IDictionaryItemService, and IWebhookService, so a failed create/update (e.g. an ISO code rejected by Umbraco's IsoCodeValidator) was silently dropped while the import still reported success. Now throws when the attempt fails, so the failure surfaces in the import results and log instead of vanishing. Fixes #1038 Co-Authored-By: Claude Sonnet 5 --- .../Serializers/DictionaryItemSerializer.cs | 10 +++++++++- .../Serialization/Serializers/LanguageSerializer.cs | 10 +++++++++- .../Serialization/Serializers/WebhookSerializer.cs | 12 +++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/uSync.Core/Serialization/Serializers/DictionaryItemSerializer.cs b/uSync.Core/Serialization/Serializers/DictionaryItemSerializer.cs index b4e658fb..b7d8772a 100644 --- a/uSync.Core/Serialization/Serializers/DictionaryItemSerializer.cs +++ b/uSync.Core/Serialization/Serializers/DictionaryItemSerializer.cs @@ -228,10 +228,18 @@ private async Task GetLevelAsync(IDictionaryItem item, int level = 0) } public override async Task SaveItemAsync(IDictionaryItem item) - => _ = item.HasIdentity + { + var attempt = item.HasIdentity ? await _dictionaryItemService.UpdateAsync(item, Constants.Security.SuperUserKey) : await _dictionaryItemService.CreateAsync(item, Constants.Security.SuperUserKey); + if (attempt.Success is false) + { + throw new InvalidOperationException( + $"Could not save dictionary item {item.ItemKey}: {attempt.Status}"); + } + } + public override Task DeleteItemAsync(IDictionaryItem item) => _dictionaryItemService.DeleteAsync(item.Key, Constants.Security.SuperUserKey); diff --git a/uSync.Core/Serialization/Serializers/LanguageSerializer.cs b/uSync.Core/Serialization/Serializers/LanguageSerializer.cs index cec96e24..a94d1a7d 100644 --- a/uSync.Core/Serialization/Serializers/LanguageSerializer.cs +++ b/uSync.Core/Serialization/Serializers/LanguageSerializer.cs @@ -152,10 +152,18 @@ public override bool IsValid(XElement node) => Task.FromResult(default(ILanguage)); public override async Task SaveItemAsync(ILanguage item) - => _ = item.HasIdentity + { + var attempt = item.HasIdentity ? await _languageService.UpdateAsync(item, Constants.Security.SuperUserKey) : await _languageService.CreateAsync(item, Constants.Security.SuperUserKey); + if (attempt.Success is false) + { + throw new InvalidOperationException( + $"Could not save language {item.IsoCode}: {attempt.Status}"); + } + } + public override Task DeleteItemAsync(ILanguage item) => _languageService.DeleteAsync(item.IsoCode, Constants.Security.SuperUserKey); diff --git a/uSync.Core/Serialization/Serializers/WebhookSerializer.cs b/uSync.Core/Serialization/Serializers/WebhookSerializer.cs index 77060cf0..40d1816d 100644 --- a/uSync.Core/Serialization/Serializers/WebhookSerializer.cs +++ b/uSync.Core/Serialization/Serializers/WebhookSerializer.cs @@ -50,7 +50,17 @@ public override string ItemAlias(IWebhook item) /// /// public override async Task SaveItemAsync(IWebhook item) - => _ = item.HasIdentity ? await _webhookService.UpdateAsync(item) : await _webhookService.CreateAsync(item); + { + var attempt = item.HasIdentity + ? await _webhookService.UpdateAsync(item) + : await _webhookService.CreateAsync(item); + + if (attempt.Success is false) + { + throw new InvalidOperationException( + $"Could not save webhook {item.Key}: {attempt.Status}"); + } + } /// protected override async Task> DeserializeCoreAsync(XElement node, SyncSerializerOptions options)