diff --git a/CHANGELOG.md b/CHANGELOG.md index 5deb9de9eb..0f1e0835c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- Fix file locking in attachments ([#1377](https://github.com/getsentry/sentry-dotnet/pull/1377)) + ## 3.12.1 ### Features diff --git a/src/Sentry/FileAttachmentContent.cs b/src/Sentry/FileAttachmentContent.cs index bd5a4bbe95..2c9fba32bb 100644 --- a/src/Sentry/FileAttachmentContent.cs +++ b/src/Sentry/FileAttachmentContent.cs @@ -15,6 +15,12 @@ public class FileAttachmentContent : IAttachmentContent public FileAttachmentContent(string filePath) => _filePath = filePath; /// - public Stream GetStream() => File.OpenRead(_filePath); + public Stream GetStream() => new FileStream( + _filePath, + FileMode.Open, + FileAccess.Read, + FileShare.ReadWrite, + bufferSize: 4096, + useAsync: true); } } diff --git a/test/Sentry.Tests/AttachmentTests.cs b/test/Sentry.Tests/AttachmentTests.cs new file mode 100644 index 0000000000..0b6f673913 --- /dev/null +++ b/test/Sentry.Tests/AttachmentTests.cs @@ -0,0 +1,42 @@ +using Sentry.Testing; + +namespace Sentry.Tests; + +public class FileAttachmentContentTests +{ + [Fact] + public void DoesNotLock() + { + // Arrange + using var tempDir = new TempDirectory(); + var filePath = Path.Combine(tempDir.Path, "MyFile.txt"); + File.WriteAllText(filePath, "Hello world!"); + + var attachment = new FileAttachmentContent(filePath); + // Act + using (var stream = attachment.GetStream()) + { + Assert.False(IsFileLocked(filePath)); + } + } + + private static bool IsFileLocked(string file) + { + try + { + using FileStream stream = new(file, FileMode.Open, FileAccess.ReadWrite); + stream.Close(); + } + catch (IOException) + { + //the file is unavailable because it is: + //still being written to + //or being processed by another thread + //or does not exist (has already been processed) + return true; + } + + //file is not locked + return false; + } +}