Skip to content

Commit 2116e6e

Browse files
authored
+semver:minor Tweak Exception Throwing Logic (#591)
* Tweak Exception Throwing Logic * File + Folder Logging * More logs
1 parent 8f7c445 commit 2116e6e

File tree

6 files changed

+133
-31
lines changed

6 files changed

+133
-31
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Tweak exception throwing to simplify stacktraces
2+
- File and folder operations will log their actions

src/ModularPipelines/Engine/Executors/PipelineExecutor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ public async Task<PipelineSummary> ExecuteAsync(List<ModuleBase> runnableModules
5050

5151
await _pipelineSetupExecutor.OnEndAsync(pipelineSummary);
5252
}
53+
54+
_exceptionContainer.ThrowExceptions();
5355

5456
if (exception != null)
5557
{
5658
throw exception;
5759
}
5860

59-
_exceptionContainer.ThrowExceptions();
60-
6161
return pipelineSummary;
6262
}
6363

src/ModularPipelines/Engine/ModuleExecutor.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,16 +231,18 @@ private async Task StartDependency(ModuleBase requestingModule, Type dependencyT
231231
}
232232
catch (Exception e) when (requestingModule.ModuleRunType == ModuleRunType.AlwaysRun)
233233
{
234-
_exceptionContainer.RegisterException(new AlwaysRunPostponedException($"{dependencyType.Name} threw an exception when {requestingModule.GetType().Name} was waiting for it as a dependency", e));
234+
_exceptionContainer.RegisterException(new AlwaysRunPostponedException(
235+
$"{dependencyType.Name} threw an exception when {requestingModule.GetType().Name} was waiting for it as a dependency",
236+
e));
235237
requestingModule.Context.Logger.LogError(e, "Ignoring Exception due to 'AlwaysRun' set");
236238
}
237-
catch (DependencyFailedException)
239+
catch (DependencyFailedException e)
238240
{
239-
throw;
241+
_exceptionContainer.RegisterException(e);
240242
}
241-
catch (Exception e)
243+
catch (PipelineCancelledException e)
242244
{
243-
throw new DependencyFailedException(e, module);
245+
_exceptionContainer.RegisterException(e);
244246
}
245247
}
246248
}

src/ModularPipelines/FileSystem/File.cs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System.Diagnostics.CodeAnalysis;
22
using System.Text.Json.Serialization;
3+
using Microsoft.Extensions.Logging;
4+
using ModularPipelines.Logging;
35

46
namespace ModularPipelines.FileSystem;
57

@@ -30,16 +32,22 @@ internal File(FileInfo fileInfo)
3032
/// <inheritdoc cref="System.IO.File.ReadAllTextAsync(string,System.Text.Encoding,System.Threading.CancellationToken)"/>>
3133
public Task<string> ReadAsync(CancellationToken cancellationToken = default)
3234
{
35+
ModuleLogger.Current.LogInformation("Reading File: {Path}", this);
36+
3337
return System.IO.File.ReadAllTextAsync(Path, cancellationToken);
3438
}
3539

3640
public Task<string[]> ReadLinesAsync(CancellationToken cancellationToken = default)
3741
{
42+
ModuleLogger.Current.LogInformation("Reading File: {Path}", this);
43+
3844
return System.IO.File.ReadAllLinesAsync(Path, cancellationToken);
3945
}
4046

4147
public Task<byte[]> ReadBytesAsync(CancellationToken cancellationToken = default)
4248
{
49+
ModuleLogger.Current.LogInformation("Reading File: {Path}", this);
50+
4351
return System.IO.File.ReadAllBytesAsync(Path, cancellationToken);
4452
}
4553

@@ -50,27 +58,37 @@ public FileStream GetStream(FileAccess fileAccess = FileAccess.ReadWrite)
5058

5159
public Task WriteAsync(string contents, CancellationToken cancellationToken = default)
5260
{
61+
ModuleLogger.Current.LogInformation("Writing to File: {Path}", this);
62+
5363
return System.IO.File.WriteAllTextAsync(Path, contents, cancellationToken);
5464
}
5565

5666
public Task WriteAsync(byte[] contents, CancellationToken cancellationToken = default)
5767
{
68+
ModuleLogger.Current.LogInformation("Writing to File: {Path}", this);
69+
5870
return System.IO.File.WriteAllBytesAsync(Path, contents, cancellationToken);
5971
}
6072

6173
public Task WriteAsync(IEnumerable<string> contents, CancellationToken cancellationToken = default)
6274
{
75+
ModuleLogger.Current.LogInformation("Writing to File: {Path}", this);
76+
6377
return System.IO.File.WriteAllLinesAsync(Path, contents, cancellationToken);
6478
}
6579

6680
public async Task WriteAsync(ReadOnlyMemory<byte> contents, CancellationToken cancellationToken = default)
6781
{
82+
ModuleLogger.Current.LogInformation("Writing to File: {Path}", this);
83+
6884
await using var fileStream = System.IO.File.Create(Path);
6985
await fileStream.WriteAsync(contents, cancellationToken);
7086
}
7187

7288
public async Task WriteAsync(Stream contents, CancellationToken cancellationToken = default)
7389
{
90+
ModuleLogger.Current.LogInformation("Writing to File: {Path}", this);
91+
7492
await using var fileStream = System.IO.File.Create(Path);
7593

7694
if (contents.CanSeek)
@@ -102,6 +120,8 @@ public async Task WriteAsync(Stream contents, CancellationToken cancellationToke
102120

103121
public File Create()
104122
{
123+
ModuleLogger.Current.LogInformation("Creating File: {Path}", this);
124+
105125
var fileStream = System.IO.File.Create(Path);
106126
fileStream.Dispose();
107127
return this;
@@ -126,34 +146,54 @@ public FileAttributes Attributes
126146
public string Extension => FileInfo.Extension;
127147

128148
/// <inheritdoc cref="FileInfo.Delete"/>>
129-
public void Delete() => FileInfo.Delete();
149+
public void Delete()
150+
{
151+
ModuleLogger.Current.LogInformation("Deleting File: {File}", this);
152+
153+
FileInfo.Delete();
154+
}
130155

131156
/// <inheritdoc cref="FileInfo.MoveTo(string)"/>>
132157
public File MoveTo(string path)
133158
{
159+
ModuleLogger.Current.LogInformation("Moving File: {Source} > {Destination}", this, path);
160+
134161
FileInfo.MoveTo(path);
135162
return this;
136163
}
137164

138165
/// <inheritdoc cref="FileInfo.MoveTo(string)"/>>
139166
public File MoveTo(Folder folder)
140167
{
168+
ModuleLogger.Current.LogInformation("Moving File: {Source} > {Destination}", this, folder);
169+
141170
folder.Create();
142171
return MoveTo(System.IO.Path.Combine(folder.Path, Name));
143172
}
144173

145174
/// <inheritdoc cref="FileInfo.CopyTo(string)"/>>
146-
public File CopyTo(string path) => FileInfo.CopyTo(path);
147-
175+
public File CopyTo(string path)
176+
{
177+
ModuleLogger.Current.LogInformation("Copying File: {Source} > {Destination}", this, path);
178+
179+
return FileInfo.CopyTo(path);
180+
}
181+
148182
public File CopyTo(Folder folder)
149183
{
184+
ModuleLogger.Current.LogInformation("Copying File: {Source} > {Destination}", this, folder);
185+
150186
folder.Create();
151187
return CopyTo(System.IO.Path.Combine(folder.Path, Name));
152188
}
153189

154190
public static File GetNewTemporaryFilePath()
155191
{
156-
return System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName())!;
192+
var path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
193+
194+
ModuleLogger.Current.LogInformation("Temporary File Path: {Path}", path);
195+
196+
return path!;
157197
}
158198

159199
public static implicit operator File?(string? path)

src/ModularPipelines/FileSystem/Folder.cs

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
using System.Diagnostics.CodeAnalysis;
2+
using System.Runtime.CompilerServices;
23
using System.Text.Json.Serialization;
34
using Microsoft.Extensions.FileSystemGlobbing;
45
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
6+
using Microsoft.Extensions.Logging;
57
using ModularPipelines.JsonUtils;
8+
using ModularPipelines.Logging;
69

710
namespace ModularPipelines.FileSystem;
811

@@ -71,14 +74,23 @@ public Folder Root
7174

7275
public Folder Create()
7376
{
77+
ModuleLogger.Current.LogInformation("Creating Folder: {Path}", this);
78+
7479
Directory.CreateDirectory(Path);
7580
return this;
7681
}
7782

78-
public void Delete() => DirectoryInfo.Delete(true);
83+
public void Delete()
84+
{
85+
ModuleLogger.Current.LogInformation("Deleting Folder: {Path}", this);
86+
87+
DirectoryInfo.Delete(true);
88+
}
7989

8090
public void Clean()
8191
{
92+
ModuleLogger.Current.LogInformation("Cleaning Folder: {Path}", this);
93+
8294
foreach (var directory in DirectoryInfo.EnumerateDirectories("*", SearchOption.TopDirectoryOnly))
8395
{
8496
directory.Delete(true);
@@ -103,40 +115,80 @@ public Folder CopyTo(string targetPath)
103115
{
104116
System.IO.File.Copy(newPath, newPath.Replace(this, targetPath), true);
105117
}
118+
119+
ModuleLogger.Current.LogInformation("Copying Folder: {Source} > {Destination}", this, targetPath);
106120

107121
return new Folder(targetPath);
108122
}
109123

110124
public Folder MoveTo(string path)
111125
{
126+
ModuleLogger.Current.LogInformation("Moving Folder: {Source} > {Destination}", this, path);
127+
112128
DirectoryInfo.MoveTo(path);
113129
return this;
114130
}
115131

116-
public Folder GetFolder(string name) => new DirectoryInfo(System.IO.Path.Combine(Path, name));
132+
public Folder GetFolder(string name)
133+
{
134+
var directoryInfo = new DirectoryInfo(System.IO.Path.Combine(Path, name));
135+
136+
ModuleLogger.Current.LogInformation("Getting Folder: {Path}", directoryInfo.FullName);
137+
138+
return directoryInfo;
139+
}
117140

118-
public Folder CreateFolder(string name) => GetFolder(name).Create();
141+
public Folder CreateFolder(string name)
142+
{
143+
var folder = GetFolder(name).Create();
144+
145+
ModuleLogger.Current.LogInformation("Creating Folder: {Path}", folder);
146+
147+
return folder;
148+
}
119149

120-
public File GetFile(string name) => new FileInfo(System.IO.Path.Combine(Path, name));
150+
public File GetFile(string name)
151+
{
152+
var fileInfo = new FileInfo(System.IO.Path.Combine(Path, name));
153+
154+
ModuleLogger.Current.LogInformation("Getting File: {Path}", fileInfo.FullName);
155+
156+
return fileInfo;
157+
}
121158

122-
public File CreateFile(string name) => GetFile(name).Create();
159+
public File CreateFile(string name)
160+
{
161+
return GetFile(name).Create();
162+
}
123163

124-
public IEnumerable<Folder> GetFolders(Func<Folder, bool> predicate) => GetFolders(predicate, _ => false);
164+
public IEnumerable<Folder> GetFolders(Func<Folder, bool> predicate, [CallerArgumentExpression("predicate")] string predicateExpression = "") => GetFolders(predicate, _ => false, predicateExpression);
125165

126-
public IEnumerable<File> GetFiles(Func<File, bool> predicate) => GetFiles(predicate, _ => false);
166+
public IEnumerable<File> GetFiles(Func<File, bool> predicate, [CallerArgumentExpression("predicate")] string predicateExpression = "") => GetFiles(predicate, _ => false, predicateExpression);
127167

128-
public IEnumerable<Folder> GetFolders(Func<Folder, bool> predicate, Func<Folder, bool> exclusionFilters) => SafeWalk.EnumerateFolders(this, exclusionFilters)
129-
.Select(x => new Folder(x))
130-
.Distinct()
131-
.Where(predicate);
168+
public IEnumerable<Folder> GetFolders(Func<Folder, bool> predicate, Func<Folder, bool> exclusionFilters, [CallerArgumentExpression("predicate")] string predicateExpression = "")
169+
{
170+
ModuleLogger.Current.LogInformation("Searching Folders in: {Path} > {Expression}", this, predicate);
132171

133-
public IEnumerable<File> GetFiles(Func<File, bool> predicate, Func<Folder, bool> directoryExclusionFilters) => SafeWalk.EnumerateFiles(this, directoryExclusionFilters)
134-
.Select(x => new File(x))
135-
.Distinct()
136-
.Where(predicate);
172+
return SafeWalk.EnumerateFolders(this, exclusionFilters)
173+
.Select(x => new Folder(x))
174+
.Distinct()
175+
.Where(predicate);
176+
}
177+
178+
public IEnumerable<File> GetFiles(Func<File, bool> predicate, Func<Folder, bool> directoryExclusionFilters, [CallerArgumentExpression("predicate")] string predicateExpression = "")
179+
{
180+
ModuleLogger.Current.LogInformation("Searching Files in: {Path} > {Expression}", this, predicate);
181+
182+
return SafeWalk.EnumerateFiles(this, directoryExclusionFilters)
183+
.Select(x => new File(x))
184+
.Distinct()
185+
.Where(predicate);
186+
}
137187

138188
public IEnumerable<File> GetFiles(string globPattern)
139189
{
190+
ModuleLogger.Current.LogInformation("Searching Files in: {Path} > {Glob}", this, globPattern);
191+
140192
return new Matcher(StringComparison.OrdinalIgnoreCase)
141193
.AddInclude(globPattern)
142194
.Execute(new DirectoryInfoWrapper(DirectoryInfo))
@@ -145,13 +197,13 @@ public IEnumerable<File> GetFiles(string globPattern)
145197
.Distinct();
146198
}
147199

148-
public File? FindFile(Func<File, bool> predicate) => FindFile(predicate, _ => false);
200+
public File? FindFile(Func<File, bool> predicate, [CallerArgumentExpression("predicate")] string predicateExpression = "") => FindFile(predicate, _ => false, predicateExpression);
149201

150-
public Folder? FindFolder(Func<Folder, bool> predicate) => FindFolder(predicate, _ => false);
202+
public Folder? FindFolder(Func<Folder, bool> predicate, [CallerArgumentExpression("predicate")] string predicateExpression = "") => FindFolder(predicate, _ => false, predicateExpression);
151203

152-
public File? FindFile(Func<File, bool> predicate, Func<Folder, bool> directoryExclusionFilters) => GetFiles(predicate, directoryExclusionFilters).FirstOrDefault();
204+
public File? FindFile(Func<File, bool> predicate, Func<Folder, bool> directoryExclusionFilters, [CallerArgumentExpression("predicate")] string predicateExpression = "") => GetFiles(predicate, directoryExclusionFilters, predicateExpression).FirstOrDefault();
153205

154-
public Folder? FindFolder(Func<Folder, bool> predicate, Func<Folder, bool> directoryExclusionFilters) => GetFolders(predicate, directoryExclusionFilters).FirstOrDefault();
206+
public Folder? FindFolder(Func<Folder, bool> predicate, Func<Folder, bool> directoryExclusionFilters, [CallerArgumentExpression("predicate")] string predicateExpression = "") => GetFolders(predicate, directoryExclusionFilters, predicateExpression).FirstOrDefault();
155207

156208
public IEnumerable<File> ListFiles()
157209
{
@@ -171,6 +223,9 @@ public static Folder CreateTemporaryFolder()
171223
{
172224
var tempDirectory = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName().Replace(".", string.Empty));
173225
Directory.CreateDirectory(tempDirectory);
226+
227+
ModuleLogger.Current.LogInformation("Creating Temporary Folder: {Path}", tempDirectory);
228+
174229
return tempDirectory!;
175230
}
176231

src/ModularPipelines/Logging/ModuleLogger.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
using System.Reflection;
22
using Microsoft.Extensions.Logging;
3+
using Microsoft.Extensions.Logging.Abstractions;
34
using ModularPipelines.Engine;
45
using ModularPipelines.Helpers;
56

67
namespace ModularPipelines.Logging;
78

89
internal abstract class ModuleLogger : IModuleLogger
910
{
10-
internal static readonly AsyncLocal<IModuleLogger> Values = new();
11+
internal static readonly AsyncLocal<IModuleLogger?> Values = new();
12+
13+
internal static ILogger Current => (Values.Value as ILogger) ?? NullLogger.Instance;
1114

1215
protected static readonly object DisposeLock = new();
1316
protected static readonly object LogLock = new();

0 commit comments

Comments
 (0)