Skip to content

Commit 8e61e49

Browse files
committed
Added: Field to Store Exceptions During Failures in Dependency Resolution
1 parent cff9703 commit 8e61e49

6 files changed

Lines changed: 132 additions & 13 deletions

File tree

source/Reloaded.Mod.Launcher.Lib/Update.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,15 +264,32 @@ public static async Task<ModDependencyResolveResult> GetMissingDependenciesToDow
264264
// Get Dependencies
265265
var resolver = DependencyResolverFactory.GetInstance(IoC.Get<AggregateNugetRepository>());
266266

267-
var results = new List<Task<ModDependencyResolveResult>>();
267+
var taskToDependencyMap = new Dictionary<Task<ModDependencyResolveResult>, string>();
268268
foreach (var dependencyItem in missingDeps.Items)
269269
foreach (var dependency in dependencyItem.Dependencies)
270-
results.Add(resolver.ResolveAsync(dependency, dependencyItem.Mod.PluginData, token));
270+
{
271+
var task = resolver.ResolveAsync(dependency, dependencyItem.Mod.PluginData, token);
272+
taskToDependencyMap[task] = dependency;
273+
}
271274

272-
await Task.WhenAll(results);
275+
// Handle each result individually to avoid stopping on failures
276+
var resolveResults = new List<ModDependencyResolveResult>();
277+
foreach (var kvp in taskToDependencyMap)
278+
{
279+
try
280+
{
281+
var taskResult = await kvp.Key;
282+
resolveResults.Add(taskResult);
283+
}
284+
catch (Exception ex)
285+
{
286+
// Create error result for unexpected exceptions that weren't caught by resolvers
287+
resolveResults.Add(ModDependencyResolveResult.FromError(kvp.Value, ex, "UnknownResolver"));
288+
}
289+
}
273290

274291
// Merge Results
275-
var result = ModDependencyResolveResult.Combine(results.Select(x => x.Result));;
292+
var result = ModDependencyResolveResult.Combine(resolveResults);
276293
if (result.NotFoundDependencies.Count <= 0)
277294
return result;
278295

source/Reloaded.Mod.Loader.Tests/Reloaded.Mod.Loader.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<OutputPath>..\Output\Tests\</OutputPath>
99
<Nullable>disable</Nullable>
1010
<NoWarn>$(NoWarn);NU1605;NU1701;MSB3270</NoWarn>
11+
<EnableWindowsTargeting>true</EnableWindowsTargeting>
1112
</PropertyGroup>
1213

1314
<ItemGroup>

source/Reloaded.Mod.Loader.Tests/Update/Providers/GameBanana/GameBananaDependencyResolverTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,33 @@ public async Task ResolveAsync_WithNoPackage_ReturnsMissing()
6868
Assert.NotEmpty(result.NotFoundDependencies);
6969
Assert.Empty(result.FoundDependencies);
7070
}
71+
72+
[Fact]
73+
public async Task ResolveAsync_WithInvalidConfig_ReturnsError()
74+
{
75+
// Arrange
76+
var config = new GameBananaUpdateResolverFactory.GameBananaConfig()
77+
{
78+
ItemId = -1, // Invalid item ID that should cause InitializeAsync to fail
79+
ItemType = "Mod"
80+
};
81+
var clonedDependency = _testEnvironmoent.TestModConfigBTuple.DeepClone();
82+
Singleton<GameBananaUpdateResolverFactory>.Instance.SetConfiguration(clonedDependency, config);
83+
var clonedOriginal = _testEnvironmoent.TestModConfigATuple.DeepClone();
84+
85+
var gameBanana = new GameBananaDependencyMetadataWriter();
86+
gameBanana.Update(clonedOriginal.Config, [clonedDependency.Config]);
87+
88+
// Act
89+
var resolver = new GameBananaDependencyResolver();
90+
var result = await resolver.ResolveAsync(clonedDependency.Config.ModId, clonedOriginal.Config.PluginData);
91+
92+
// Assert
93+
Assert.Single(result.Errors);
94+
Assert.Equal(clonedDependency.Config.ModId, result.Errors[0].PackageId);
95+
Assert.Equal(nameof(GameBananaDependencyResolver), result.Errors[0].Resolver);
96+
Assert.NotNull(result.Errors[0].Exception);
97+
Assert.Contains(clonedDependency.Config.ModId, result.NotFoundDependencies);
98+
Assert.Empty(result.FoundDependencies);
99+
}
71100
}

source/Reloaded.Mod.Loader.Update/Interfaces/IDependencyResolver.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ public class ModDependencyResolveResult
2929
/// </summary>
3030
public HashSet<string> NotFoundDependencies { get; } = new HashSet<string>();
3131

32+
/// <summary>
33+
/// List of errors that occurred during dependency resolution.
34+
/// </summary>
35+
public List<DependencyResolveError> Errors { get; } = new List<DependencyResolveError>();
36+
3237
/// <summary>
3338
/// Combines the results of multiple resolve operations.
3439
/// </summary>
@@ -59,6 +64,9 @@ public static ModDependencyResolveResult Combine(IEnumerable<ModDependencyResolv
5964

6065
foreach (var notFound in result.NotFoundDependencies)
6166
returnValue.NotFoundDependencies.Add(notFound);
67+
68+
foreach (var error in result.Errors)
69+
returnValue.Errors.Add(error);
6270
}
6371

6472
// Remove dependencies that were found from the notFound set.
@@ -68,4 +76,53 @@ public static ModDependencyResolveResult Combine(IEnumerable<ModDependencyResolv
6876
returnValue.FoundDependencies.AddRange(idToNewestVersion.Values);
6977
return returnValue;
7078
}
79+
80+
/// <summary>
81+
/// Creates a result with an error for a specific package.
82+
/// </summary>
83+
/// <param name="packageId">The package ID that failed to resolve.</param>
84+
/// <param name="exception">The exception that occurred during resolution.</param>
85+
/// <param name="resolver">The resolver that caused the error.</param>
86+
/// <returns>A result containing the error information.</returns>
87+
public static ModDependencyResolveResult FromError(string packageId, Exception exception, string resolver)
88+
{
89+
var result = new ModDependencyResolveResult();
90+
result.Errors.Add(new DependencyResolveError(packageId, exception, resolver));
91+
result.NotFoundDependencies.Add(packageId);
92+
return result;
93+
}
94+
}
95+
96+
/// <summary>
97+
/// Represents an error that occurred during dependency resolution.
98+
/// </summary>
99+
public class DependencyResolveError
100+
{
101+
/// <summary>
102+
/// The package ID that failed to resolve.
103+
/// </summary>
104+
public string PackageId { get; }
105+
106+
/// <summary>
107+
/// The exception that occurred during resolution.
108+
/// </summary>
109+
public Exception Exception { get; }
110+
111+
/// <summary>
112+
/// The name of the resolver that caused the error.
113+
/// </summary>
114+
public string Resolver { get; }
115+
116+
/// <summary>
117+
/// Creates a new dependency resolve error.
118+
/// </summary>
119+
/// <param name="packageId">The package ID that failed to resolve.</param>
120+
/// <param name="exception">The exception that occurred during resolution.</param>
121+
/// <param name="resolver">The name of the resolver that caused the error.</param>
122+
public DependencyResolveError(string packageId, Exception exception, string resolver)
123+
{
124+
PackageId = packageId;
125+
Exception = exception;
126+
Resolver = resolver;
127+
}
71128
}

source/Reloaded.Mod.Loader.Update/Providers/GameBanana/GameBananaDependencyResolver.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,19 @@ public async Task<ModDependencyResolveResult> ResolveAsync(string packageId, Dic
2727
ModType = gbConfig.Config.ItemType
2828
}, new CommonPackageResolverSettings() { MetadataFileName = gbConfig.ReleaseMetadataName });
2929

30-
await resolver.InitializeAsync();
31-
32-
result.FoundDependencies.Add(new UpdateDownloadablePackage(resolver)
30+
try
31+
{
32+
await resolver.InitializeAsync();
33+
34+
result.FoundDependencies.Add(new UpdateDownloadablePackage(resolver)
35+
{
36+
Id = packageId
37+
});
38+
}
39+
catch (Exception ex)
3340
{
34-
Id = packageId
35-
});
41+
return ModDependencyResolveResult.FromError(packageId, ex, nameof(GameBananaDependencyResolver));
42+
}
3643

3744
return result;
3845
}

source/Reloaded.Mod.Loader.Update/Providers/GitHub/GitHubDependencyResolver.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,19 @@ public async Task<ModDependencyResolveResult> ResolveAsync(string packageId, Dic
3131
InheritVersionFromTag = gitConfig.Config.UseReleaseTag
3232
}, new CommonPackageResolverSettings() { MetadataFileName = gitConfig.ReleaseMetadataName });
3333

34-
await ((IPackageResolver)resolver).InitializeAsync();
35-
result.FoundDependencies.Add(new UpdateDownloadablePackage(resolver)
34+
try
3635
{
37-
Id = packageId
38-
});
36+
await ((IPackageResolver)resolver).InitializeAsync();
37+
38+
result.FoundDependencies.Add(new UpdateDownloadablePackage(resolver)
39+
{
40+
Id = packageId
41+
});
42+
}
43+
catch (Exception ex)
44+
{
45+
return ModDependencyResolveResult.FromError(packageId, ex, nameof(GitHubDependencyResolver));
46+
}
3947

4048
return result;
4149
}

0 commit comments

Comments
 (0)