Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Route file writing through FileSystem #3614

Merged
merged 19 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- Added a flag to options `DisableFileWrite` to allow users to opt-out of all file writing operations. Note that toggling this will affect features such as offline caching and auto-session tracking and release health as these rely on some file persistency ([#3614](https://github.com/getsentry/sentry-dotnet/pull/3614))
- All exceptions are now added as breadcrumbs on future events. Previously this was only the case for exceptions captured via the `Sentry.SeriLog` or `Sentry.Extensions.Logging` integrations. ([#3584](https://github.com/getsentry/sentry-dotnet/pull/3584))

### Fixes
Expand Down
2 changes: 2 additions & 0 deletions src/Sentry/BindableSentryOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ internal partial class BindableSentryOptions
public string? CacheDirectoryPath { get; set; }
public bool? CaptureFailedRequests { get; set; }
public List<string>? FailedRequestTargets { get; set; }
public bool? DisableFileWrite { get; set; }
public TimeSpan? InitCacheFlushTimeout { get; set; }
public Dictionary<string, string>? DefaultTags { get; set; }
public bool? EnableTracing { get; set; }
Expand Down Expand Up @@ -81,6 +82,7 @@ public void ApplyTo(SentryOptions options)
options.CacheDirectoryPath = CacheDirectoryPath ?? options.CacheDirectoryPath;
options.CaptureFailedRequests = CaptureFailedRequests ?? options.CaptureFailedRequests;
options.FailedRequestTargets = FailedRequestTargets?.Select(s => new SubstringOrRegexPattern(s)).ToList() ?? options.FailedRequestTargets;
options.DisableFileWrite = DisableFileWrite ?? options.DisableFileWrite;
options.InitCacheFlushTimeout = InitCacheFlushTimeout ?? options.InitCacheFlushTimeout;
options.DefaultTags = DefaultTags ?? options.DefaultTags;
#pragma warning disable CS0618 // Type or member is obsolete
Expand Down
16 changes: 10 additions & 6 deletions src/Sentry/GlobalSessionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
_options = options;
_clock = clock ?? SystemClock.Clock;
_persistedSessionProvider = persistedSessionProvider
?? (filePath => Json.Load(filePath, PersistedSessionUpdate.FromJson));
?? (filePath => Json.Load(_options.FileSystem, filePath, PersistedSessionUpdate.FromJson));

// TODO: session file should really be process-isolated, but we
// don't have a proper mechanism for that right now.
Expand All @@ -53,14 +53,18 @@

try
{
Directory.CreateDirectory(_persistenceDirectoryPath);
_options.LogDebug("Creating persistence directory for session file at '{0}'.", _persistenceDirectoryPath);

_options.LogDebug("Created persistence directory for session file '{0}'.", _persistenceDirectoryPath);
if (!_options.FileSystem.CreateDirectory(_persistenceDirectoryPath))

Check failure on line 58 in src/Sentry/GlobalSessionManager.cs

View workflow job for this annotation

GitHub Actions / build

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 58 in src/Sentry/GlobalSessionManager.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 58 in src/Sentry/GlobalSessionManager.cs

View workflow job for this annotation

GitHub Actions / Analyze

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 58 in src/Sentry/GlobalSessionManager.cs

View workflow job for this annotation

GitHub Actions / Analyze

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 58 in src/Sentry/GlobalSessionManager.cs

View workflow job for this annotation

GitHub Actions / build

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 58 in src/Sentry/GlobalSessionManager.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 58 in src/Sentry/GlobalSessionManager.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 58 in src/Sentry/GlobalSessionManager.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'
{
_options.LogError("Failed to create persistent directory for session file.");
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
return;
}

var filePath = Path.Combine(_persistenceDirectoryPath, PersistedSessionFileName);

var persistedSessionUpdate = new PersistedSessionUpdate(update, pauseTimestamp);
persistedSessionUpdate.WriteToFile(filePath, _options.DiagnosticLogger);
persistedSessionUpdate.WriteToFile(_options.FileSystem, filePath, _options.DiagnosticLogger);

_options.LogDebug("Persisted session to a file '{0}'.", filePath);
}
Expand All @@ -86,7 +90,7 @@
{
try
{
var contents = File.ReadAllText(filePath);
var contents = _options.FileSystem.ReadAllTextFromFile(filePath);
_options.LogDebug("Deleting persisted session file with contents: {0}", contents);
}
catch (Exception ex)
Expand All @@ -95,7 +99,7 @@
}
}

File.Delete(filePath);
_options.FileSystem.DeleteFile(filePath);

_options.LogInfo("Deleted persisted session file '{0}'.", filePath);
}
Expand Down
27 changes: 23 additions & 4 deletions src/Sentry/Http/HttpTransportBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -386,13 +386,22 @@
var destination = Path.Combine(destinationDirectory, "envelope_too_large",
(eventId ?? SentryId.Create()).ToString());

Directory.CreateDirectory(Path.GetDirectoryName(destination)!);
if (!_options.FileSystem.CreateDirectory(Path.GetDirectoryName(destination)!))

Check failure on line 389 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / build

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 389 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 389 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / Analyze

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 389 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / Analyze

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 389 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / build

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 389 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 389 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 389 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'
{
_options.LogError("Failed to create directory to store the envelope.");
return;
}

var envelopeFile = File.Create(destination);
var envelopeFile = _options.FileSystem.CreateFileForWriting(destination);
if (envelopeFile == Stream.Null)
{
_options.LogError("Failed to create envelope file.");
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
return;
}

using (envelopeFile)
{
envelope.Serialize(envelopeFile, _options.DiagnosticLogger);

Check failure on line 404 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'stream' in 'void Envelope.Serialize(Stream stream, IDiagnosticLogger? logger)'.

Check failure on line 404 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Possible null reference argument for parameter 'stream' in 'void Envelope.Serialize(Stream stream, IDiagnosticLogger? logger)'.

Check failure on line 404 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'stream' in 'void Envelope.Serialize(Stream stream, IDiagnosticLogger? logger)'.

Check failure on line 404 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Possible null reference argument for parameter 'stream' in 'void Envelope.Serialize(Stream stream, IDiagnosticLogger? logger)'.

Check failure on line 404 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Possible null reference argument for parameter 'stream' in 'void Envelope.Serialize(Stream stream, IDiagnosticLogger? logger)'.
envelopeFile.Flush();
_options.LogInfo("{0}: Envelope's {1} bytes written to: {2}",
_typeName, envelopeFile.Length, destination);
Expand Down Expand Up @@ -442,9 +451,19 @@
var destination = Path.Combine(destinationDirectory, "envelope_too_large",
(eventId ?? SentryId.Create()).ToString());

Directory.CreateDirectory(Path.GetDirectoryName(destination)!);
if (!_options.FileSystem.CreateDirectory(Path.GetDirectoryName(destination)!))

Check failure on line 454 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / build

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 454 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 454 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / Analyze

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 454 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / Analyze

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 454 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / build

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 454 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 454 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 454 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'
{
_options.LogError("Failed to create directory to store the envelope.");
return;
}

var envelopeFile = _options.FileSystem.CreateFileForWriting(destination);
if (envelopeFile == Stream.Null)
{
_options.LogError("Failed to create envelope file.");
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
return;
}

var envelopeFile = File.Create(destination);
#if NETFRAMEWORK || NETSTANDARD2_0
using (envelopeFile)
#else
Expand All @@ -452,7 +471,7 @@
#endif
{
await envelope
.SerializeAsync(envelopeFile, _options.DiagnosticLogger, cancellationToken)

Check failure on line 474 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'stream' in 'Task Envelope.SerializeAsync(Stream stream, IDiagnosticLogger? logger, CancellationToken cancellationToken = default(CancellationToken))'.

Check failure on line 474 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Possible null reference argument for parameter 'stream' in 'Task Envelope.SerializeAsync(Stream stream, IDiagnosticLogger? logger, CancellationToken cancellationToken = default(CancellationToken))'.

Check failure on line 474 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'stream' in 'Task Envelope.SerializeAsync(Stream stream, IDiagnosticLogger? logger, CancellationToken cancellationToken = default(CancellationToken))'.

Check failure on line 474 in src/Sentry/Http/HttpTransportBase.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Possible null reference argument for parameter 'stream' in 'Task Envelope.SerializeAsync(Stream stream, IDiagnosticLogger? logger, CancellationToken cancellationToken = default(CancellationToken))'.
.ConfigureAwait(false);
await envelopeFile.FlushAsync(cancellationToken).ConfigureAwait(false);
_options.LogInfo("{0}: Envelope's {1} bytes written to: {2}",
Expand Down
10 changes: 8 additions & 2 deletions src/Sentry/ISentryJsonSerializable.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Sentry.Extensibility;
using Sentry.Internal;

namespace Sentry;

Expand All @@ -19,10 +20,15 @@

internal static class JsonSerializableExtensions
{
public static void WriteToFile(this ISentryJsonSerializable serializable, string filePath, IDiagnosticLogger? logger)
public static void WriteToFile(this ISentryJsonSerializable serializable, IFileSystem fileSystem, string filePath, IDiagnosticLogger? logger)
{
using var file = File.Create(filePath);
using var file = fileSystem.CreateFileForWriting(filePath);
if (file == Stream.Null)
{
return;
}

using var writer = new Utf8JsonWriter(file);

Check failure on line 31 in src/Sentry/ISentryJsonSerializable.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'utf8Json' in 'Utf8JsonWriter.Utf8JsonWriter(Stream utf8Json, JsonWriterOptions options = default(JsonWriterOptions))'.

Check failure on line 31 in src/Sentry/ISentryJsonSerializable.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Possible null reference argument for parameter 'utf8Json' in 'Utf8JsonWriter.Utf8JsonWriter(Stream utf8Json, JsonWriterOptions options = default(JsonWriterOptions))'.

Check failure on line 31 in src/Sentry/ISentryJsonSerializable.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'utf8Json' in 'Utf8JsonWriter.Utf8JsonWriter(Stream utf8Json, JsonWriterOptions options = default(JsonWriterOptions))'.

Check failure on line 31 in src/Sentry/ISentryJsonSerializable.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Possible null reference argument for parameter 'utf8Json' in 'Utf8JsonWriter.Utf8JsonWriter(Stream utf8Json, JsonWriterOptions options = default(JsonWriterOptions))'.

Check failure on line 31 in src/Sentry/ISentryJsonSerializable.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Possible null reference argument for parameter 'utf8Json' in 'Utf8JsonWriter.Utf8JsonWriter(Stream utf8Json, JsonWriterOptions options = default(JsonWriterOptions))'.

serializable.WriteTo(writer, logger);
writer.Flush();
Expand Down
3 changes: 2 additions & 1 deletion src/Sentry/Internal/DebugStackTrace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,9 @@
{
return reader.Invoke(assemblyName);
}
var assembly = File.OpenRead(assemblyName);

var assembly = options.FileSystem.OpenFileForReading(assemblyName);
return new PEReader(assembly);

Check failure on line 531 in src/Sentry/Internal/DebugStackTrace.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'peStream' in 'PEReader.PEReader(Stream peStream)'.

Check failure on line 531 in src/Sentry/Internal/DebugStackTrace.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'peStream' in 'PEReader.PEReader(Stream peStream)'.

Check failure on line 531 in src/Sentry/Internal/DebugStackTrace.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Possible null reference argument for parameter 'peStream' in 'PEReader.PEReader(Stream peStream)'.
}
catch (Exception)
{
Expand Down
109 changes: 93 additions & 16 deletions src/Sentry/Internal/FileSystem.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using Sentry.Extensibility;

namespace Sentry.Internal;

internal class FileSystem : IFileSystem
{
public static IFileSystem Instance { get; } = new FileSystem();
private readonly SentryOptions? _options;

private FileSystem()
public FileSystem(SentryOptions? options)
{
_options = options;
}

public IEnumerable<string> EnumerateFiles(string path) => Directory.EnumerateFiles(path);
Expand All @@ -16,38 +19,112 @@ public IEnumerable<string> EnumerateFiles(string path, string searchPattern) =>
public IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption) =>
Directory.EnumerateFiles(path, searchPattern, searchOption);

public void CreateDirectory(string path) => Directory.CreateDirectory(path);
public DirectoryInfo? CreateDirectory(string path)
{
if (!_options?.DisableFileWrite is false)
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
{
_options?.LogDebug("Skipping creating directory. Writing to file system has been explicitly disabled.");
return null;
}
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved

return Directory.CreateDirectory(path);
}

public bool? DeleteDirectory(string path, bool recursive = false)
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
{
if (!_options?.DisableFileWrite is false)
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
{
_options?.LogDebug("Skipping deleting directory. Writing to file system has been explicitly disabled.");
return false;
}

public void DeleteDirectory(string path, bool recursive = false) => Directory.Delete(path, recursive);
Directory.Delete(path, recursive);
return !Directory.Exists(path);
}

public bool DirectoryExists(string path) => Directory.Exists(path);

public bool FileExists(string path) => File.Exists(path);

public void MoveFile(string sourceFileName, string destFileName, bool overwrite = false)
public bool? MoveFile(string sourceFileName, string destFileName, bool overwrite = false)
{
if (!_options?.DisableFileWrite is false)
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
{
_options?.LogDebug("Skipping moving file. Writing to file system has been explicitly disabled.");
return null;
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
}

#if NETCOREAPP3_0_OR_GREATER
File.Move(sourceFileName, destFileName, overwrite);
#else
if (overwrite)
{
File.Copy(sourceFileName, destFileName, overwrite: true);
File.Delete(sourceFileName);
}
else
{
File.Move(sourceFileName, destFileName);
}
if (overwrite)
{
File.Copy(sourceFileName, destFileName, overwrite: true);
File.Delete(sourceFileName);
}
else
{
File.Move(sourceFileName, destFileName);
}
#endif

if (File.Exists(sourceFileName) || !File.Exists(destFileName))
{
return false;
}

return true;
}

public void DeleteFile(string path) => File.Delete(path);
public bool? DeleteFile(string path)
{
if (!_options?.DisableFileWrite is false)
bitsandfoxes marked this conversation as resolved.
Show resolved Hide resolved
{
_options?.LogDebug("Skipping deleting file. Writing to file system has been explicitly disabled.");
return null;
}

File.Delete(path);
return !File.Exists(path);
}

public DateTimeOffset GetFileCreationTime(string path) => new FileInfo(path).CreationTimeUtc;

public string ReadAllTextFromFile(string path) => File.ReadAllText(path);

public Stream OpenFileForReading(string path) => File.OpenRead(path);

public Stream CreateFileForWriting(string path) => File.Create(path);
public Stream OpenFileForReading(string path, bool useAsync, FileMode fileMode = FileMode.Open, FileAccess fileAccess = FileAccess.Read, FileShare fileShare = FileShare.ReadWrite, int bufferSize = 4096)
{
return new FileStream(
path,
fileMode,
fileAccess,
fileShare,
bufferSize: bufferSize,
useAsync: useAsync);
}

public Stream? CreateFileForWriting(string path)
{
if (!_options?.DisableFileWrite is false)
{
_options?.LogDebug("Skipping file for writing. Writing to file system has been explicitly disabled.");
return null;
}

return File.Create(path);
}

public bool? WriteAllTextToFile(string path, string contents)
{
if (!_options?.DisableFileWrite is false)
{
_options?.LogDebug("Skipping writing all text to file. Writing to file system has been explicitly disabled.");
return null;
}

File.WriteAllText(path, contents);
return File.Exists(path);
}
}
21 changes: 14 additions & 7 deletions src/Sentry/Internal/IFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ internal interface IFileSystem
IEnumerable<string> EnumerateFiles(string path);
IEnumerable<string> EnumerateFiles(string path, string searchPattern);
IEnumerable<string> EnumerateFiles(string path, string searchPattern, SearchOption searchOption);
void CreateDirectory(string path);
void DeleteDirectory(string path, bool recursive = false);
DirectoryInfo? CreateDirectory(string path);
bool? DeleteDirectory(string path, bool recursive = false);
bool DirectoryExists(string path);
bool FileExists(string path);
void MoveFile(string sourceFileName, string destFileName, bool overwrite = false);
void DeleteFile(string path);
bool? MoveFile(string sourceFileName, string destFileName, bool overwrite = false);
bool? DeleteFile(string path);
DateTimeOffset GetFileCreationTime(string path);
string ReadAllTextFromFile(string file);
Stream OpenFileForReading(string path);
Stream CreateFileForWriting(string path);
string? ReadAllTextFromFile(string file);
Stream? OpenFileForReading(string path);
Stream? OpenFileForReading(string path,
bool useAsync,
FileMode fileMode = FileMode.Open,
FileAccess fileAccess = FileAccess.Read,
FileShare fileShare = FileShare.ReadWrite,
int bufferSize = 4096);
Stream? CreateFileForWriting(string path);
bool? WriteAllTextToFile(string path, string contents);
}
23 changes: 19 additions & 4 deletions src/Sentry/Internal/InstallationIdHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,43 @@

private string? TryGetPersistentInstallationId()
{
if (options.DisableFileWrite)
{
options.LogDebug("File write has been disabled via the options. Skipping trying to get persistent installation ID.");
return null;
}

try
{
var rootPath = options.CacheDirectoryPath ??
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var directoryPath = Path.Combine(rootPath, "Sentry", options.Dsn!.GetHashString());
var fileSystem = options.FileSystem;

Directory.CreateDirectory(directoryPath);
if (!fileSystem.CreateDirectory(directoryPath))

Check failure on line 63 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / build

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 63 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 63 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 63 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 63 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / build

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 63 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'

Check failure on line 63 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Operator '!' cannot be applied to operand of type 'DirectoryInfo'
{
options.LogDebug("Failed to create a directory for installation ID file ({0}).", directoryPath);
return null;
}

options.LogDebug("Created directory for installation ID file ({0}).", directoryPath);

var filePath = Path.Combine(directoryPath, ".installation");

// Read installation ID stored in a file
if (File.Exists(filePath))
if (fileSystem.FileExists(filePath))
{
return File.ReadAllText(filePath);
return fileSystem.ReadAllTextFromFile(filePath);
}
options.LogDebug("File containing installation ID does not exist ({0}).", filePath);

// Generate new installation ID and store it in a file
var id = Guid.NewGuid().ToString();
File.WriteAllText(filePath, id);
if (!fileSystem.WriteAllTextToFile(filePath, id))

Check failure on line 82 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / build

Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)

Check failure on line 82 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)

Check failure on line 82 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze

Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)

Check failure on line 82 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze

Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)

Check failure on line 82 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)

Check failure on line 82 in src/Sentry/Internal/InstallationIdHelper.cs

View workflow job for this annotation

GitHub Actions / .NET (macos-latest)

Cannot implicitly convert type 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)
{
options.LogDebug("Failed to write Installation ID to file ({0}).", filePath);
return null;
}

options.LogDebug("Saved installation ID '{0}' to file '{1}'.", id, filePath);
return id;
Expand Down
4 changes: 2 additions & 2 deletions src/Sentry/Internal/Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
return factory.Invoke(jsonDocument.RootElement);
}

public static T Load<T>(string filePath, Func<JsonElement, T> factory)
public static T Load<T>(IFileSystem fileSystem, string filePath, Func<JsonElement, T> factory)
{
using var file = File.OpenRead(filePath);
using var file = fileSystem.OpenFileForReading(filePath);
using var jsonDocument = JsonDocument.Parse(file);

Check failure on line 20 in src/Sentry/Internal/Json.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'utf8Json' in 'JsonDocument JsonDocument.Parse(Stream utf8Json, JsonDocumentOptions options = default(JsonDocumentOptions))'.

Check failure on line 20 in src/Sentry/Internal/Json.cs

View workflow job for this annotation

GitHub Actions / .NET (ubuntu-latest)

Possible null reference argument for parameter 'utf8Json' in 'JsonDocument JsonDocument.Parse(Stream utf8Json, JsonDocumentOptions options = default(JsonDocumentOptions))'.

Check failure on line 20 in src/Sentry/Internal/Json.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'utf8Json' in 'JsonDocument JsonDocument.Parse(Stream utf8Json, JsonDocumentOptions options = default(JsonDocumentOptions))'.

Check failure on line 20 in src/Sentry/Internal/Json.cs

View workflow job for this annotation

GitHub Actions / .NET (windows-latest)

Possible null reference argument for parameter 'utf8Json' in 'JsonDocument JsonDocument.Parse(Stream utf8Json, JsonDocumentOptions options = default(JsonDocumentOptions))'.
return factory.Invoke(jsonDocument.RootElement);
}
}
Loading
Loading