diff --git a/src/OutlookAddin.Core/Services/AttachmentSaveService.cs b/src/OutlookAddin.Core/Services/AttachmentSaveService.cs index 3c5ccaa..9af7f5a 100644 --- a/src/OutlookAddin.Core/Services/AttachmentSaveService.cs +++ b/src/OutlookAddin.Core/Services/AttachmentSaveService.cs @@ -59,6 +59,12 @@ namespace MarcusLaw.OutlookAddin.Core.Services await _client.UploadAttachmentToNetworkStorageAsync( uploaded.Id, trimmedFolder, cancellationToken).ConfigureAwait(false); + // Step 3: verify the file actually landed on the share — + // the server can return 200 yet leave nothing on disk + // when a downstream WebDAV proxy silently fails. Read + // the folder back and look for our filename. + await VerifyArrivedAsync(att.Name, trimmedFolder, cancellationToken).ConfigureAwait(false); + _logger.Information( "Saved attachment {Name} → {Path} (attachmentId={AttachmentId})", att.Name, trimmedFolder, uploaded.Id); @@ -99,5 +105,54 @@ namespace MarcusLaw.OutlookAddin.Core.Services return summary; } + + /// + /// Post-upload sanity check: list the folder we just wrote into + /// and confirm a file with the same (possibly sanitized) name + /// shows up. Diagnostic only — does not change the outcome. If + /// the file isn't there, log a WARNING with everything that IS + /// in the folder so we can spot the actual server-side path. + /// + private async Task VerifyArrivedAsync(string expectedName, string folderPath, CancellationToken ct) + { + try + { + var items = await _client.ListNetworkStorageFolderAsync(folderPath, ct).ConfigureAwait(false); + var trimmedExpected = expectedName.Trim().TrimStart('-', ' ').TrimEnd('-', ' '); + bool found = false; + foreach (var it in items) + { + if (it.IsFolder) continue; + if (string.Equals(it.Name, expectedName, StringComparison.Ordinal) || + string.Equals(it.Name, trimmedExpected, StringComparison.Ordinal)) + { + found = true; + break; + } + } + if (!found) + { + var names = new List(); + foreach (var it in items) + { + if (it.IsFolder) continue; + names.Add(it.Name); + } + _logger.Warning( + "Post-upload verify: expected '{Expected}' under '{Path}' but it's NOT in the listing. " + + "Server reported the upload as successful but the file is not on the share. " + + "Files currently in that folder: [{Files}]", + expectedName, folderPath, string.Join(", ", names)); + } + else + { + _logger.Information("Post-upload verify: '{Expected}' present under '{Path}'", expectedName, folderPath); + } + } + catch (Exception ex) + { + _logger.Warning(ex, "Post-upload verify failed for '{Expected}' under '{Path}'", expectedName, folderPath); + } + } } }