Skip to content

Commit 21bb7c3

Browse files
thomhurstclaude
andcommitted
fix: address PR #1895 review comments
- Fix null reference in PackProjectsModule.cs using null-conditional operator - Fix documentation: classes are deprecated, not removed - Fix property pattern syntax in design doc example - Update implementation plan to reflect custom JsonConverter usage - Document StackTrace serialization limitation in exception converter Addresses PR #1895 review feedback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent fa184c0 commit 21bb7c3

File tree

4 files changed

+15
-8
lines changed

4 files changed

+15
-8
lines changed

docs/plans/2026-01-07-module-result-discriminated-union-implementation.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,10 @@ namespace ModularPipelines.Models;
144144
/// }
145145
/// </code>
146146
/// </example>
147-
[JsonDerivedType(typeof(Success), "Success")]
148-
[JsonDerivedType(typeof(Failure), "Failure")]
149-
[JsonDerivedType(typeof(Skipped), "Skipped")]
147+
// NOTE: Actual implementation uses a custom JsonConverter instead of JsonDerivedType
148+
// because JsonDerivedType doesn't handle generic types well at runtime.
149+
// The actual attribute is: [JsonConverter(typeof(ModuleResultJsonConverterFactory))]
150+
[JsonConverter(typeof(ModuleResultJsonConverterFactory))]
150151
public abstract record ModuleResult<T> : IModuleResult
151152
{
152153
// === Metadata (available on all outcomes) ===

docs/plans/2026-01-07-module-result-discriminated-union.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ switch (result)
7676
case ModuleResult<string>.Failure { Exception: var ex }:
7777
Console.WriteLine($"Failed: {ex.Message}");
7878
break;
79-
case ModuleResult<string>.Skipped { Decision.Reason: var reason }:
80-
Console.WriteLine($"Skipped: {reason}");
79+
case ModuleResult<string>.Skipped { Decision: var skip }:
80+
Console.WriteLine($"Skipped: {skip.Reason}");
8181
break;
8282
}
8383
```
@@ -172,11 +172,13 @@ internal static Skipped CreateSkipped(SkipDecision decision, ModuleExecutionCont
172172

173173
### Removed
174174
- `ModuleResult<T>.Value` property (the throwing one)
175-
- `ModuleFailedException` class
176-
- `ModuleSkippedException` class
177175
- `SkippedModuleResult<T>` subclass
178176
- `TimedOutModuleResult<T>` subclass
179177

178+
### Deprecated (not removed)
179+
- `ModuleFailedException` class (marked with [Obsolete])
180+
- `ModuleSkippedException` class (marked with [Obsolete])
181+
180182
### Preserved
181183
- `ModuleResultType` property (now computed)
182184
- `IModuleResult` interface

src/ModularPipelines.Build/Modules/PackProjectsModule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class PackProjectsModule : Module<CommandResult[]>
3838
var others = await projectFiles.ValueOrDefault!.Others
3939
.Where(x =>
4040
{
41-
if (changedFiles.SkipDecisionOrDefault.ShouldSkip)
41+
if (changedFiles.SkipDecisionOrDefault?.ShouldSkip == true)
4242
{
4343
return true;
4444
}

src/ModularPipelines/Models/ModuleResult.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@ internal sealed class ExceptionJsonConverter : JsonConverter<Exception>
335335
}
336336
}
337337

338+
// NOTE: StackTrace is intentionally not restored during deserialization.
339+
// Setting the StackTrace property via reflection is fragile and can cause issues.
340+
// The original stack trace is preserved in the JSON for diagnostic purposes,
341+
// but deserialized exceptions will have a new stack trace from deserialization.
338342
return new Exception(message ?? "Deserialized exception");
339343
}
340344

0 commit comments

Comments
 (0)