Skip to content

Commit d172fc6

Browse files
committed
Add an Exception interceptor to catch ReflectionTypeLoadException and properly blame broken DLLs
1 parent ff63723 commit d172fc6

3 files changed

Lines changed: 63 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Reflection;
6+
using UnityEngine;
7+
using Object = UnityEngine.Object;
8+
9+
namespace ModuleManager.UnityLogHandle
10+
{
11+
class InterceptLogHandler : ILogHandler
12+
{
13+
private readonly ILogHandler baseLogHandler;
14+
private readonly List<Assembly> brokenAssemblies = new List<Assembly>();
15+
private readonly int gamePathLength;
16+
17+
public static string Warnings { get; private set; } = "";
18+
19+
public InterceptLogHandler()
20+
{
21+
baseLogHandler = Debug.unityLogger.logHandler;
22+
Debug.unityLogger.logHandler = this;
23+
gamePathLength = Path.GetFullPath(KSPUtil.ApplicationRootPath).Length;
24+
}
25+
26+
public void LogFormat(LogType logType, Object context, string format, params object[] args)
27+
{
28+
baseLogHandler.LogFormat(logType, context, format, args);
29+
}
30+
31+
public void LogException(Exception exception, Object context)
32+
{
33+
baseLogHandler.LogException(exception, context);
34+
35+
if (exception is ReflectionTypeLoadException ex)
36+
{
37+
ModuleManager.Log("Intercepted a ReflectionTypeLoadException. List of broken DLLs:");
38+
var assemblies = ex.Types.Where(x => x != null).Select(x => x.Assembly).Distinct();
39+
foreach (Assembly assembly in assemblies)
40+
{
41+
if (Warnings == "")
42+
{
43+
Warnings = "ModuleManager mod(s) DLL that are not compatible with this version of KSP\n";
44+
}
45+
if (!brokenAssemblies.Contains(assembly))
46+
{
47+
brokenAssemblies.Add(assembly);
48+
Warnings += assembly.GetName().Name + " " + assembly.GetName().Version + " " + assembly.Location.Remove(0, gamePathLength) + "\n";
49+
}
50+
ModuleManager.Log(assembly.GetName().Name + " " + assembly.GetName().Version + " " + assembly.Location.Remove(0, gamePathLength));
51+
}
52+
}
53+
baseLogHandler.LogException(exception, context);
54+
}
55+
}
56+
}

ModuleManager/ModuleManager.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using ModuleManager.Cats;
1212
using ModuleManager.Extensions;
1313
using ModuleManager.Logging;
14+
using ModuleManager.UnityLogHandle;
1415

1516
namespace ModuleManager
1617
{
@@ -40,6 +41,8 @@ public class ModuleManager : MonoBehaviour
4041

4142
private MMPatchRunner patchRunner;
4243

44+
private InterceptLogHandler interceptLogHandler;
45+
4346
#endregion state
4447

4548
private static bool loadedInScene;
@@ -196,6 +199,7 @@ private void Start()
196199
}
197200
}
198201
}
202+
interceptLogHandler = new InterceptLogHandler();
199203
}
200204

201205
private TextMeshProUGUI CreateTextObject(Canvas canvas, string name)
@@ -289,6 +293,7 @@ internal void Update()
289293
{
290294
if (warning)
291295
{
296+
warning.text = InterceptLogHandler.Warnings;
292297
h = warning.text.Length > 0 ? warning.textBounds.size.y : 0;
293298
offsetY = offsetY + h;
294299
warning.rectTransform.localPosition = new Vector3(0, offsetY);

ModuleManager/ModuleManager.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
<Compile Include="Threading\ITaskStatus.cs" />
109109
<Compile Include="Threading\TaskStatus.cs" />
110110
<Compile Include="Threading\TaskStatusWrapper.cs" />
111+
<Compile Include="ExceptionIntercept\InterceptLogHandler.cs" />
111112
<Compile Include="Utils\Counter.cs" />
112113
<Compile Include="Utils\FileUtils.cs" />
113114
<Compile Include="CustomConfigsManager.cs" />
@@ -194,6 +195,7 @@
194195
<ItemGroup>
195196
<None Include="Properties\rainbow2.png" />
196197
</ItemGroup>
198+
<ItemGroup />
197199
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
198200
<PropertyGroup>
199201
<PostBuildEvent>sh -c "TARGET_PATH='$(TargetPath)' TARGET_DIR='$(TargetDir)' TARGET_NAME='$(TargetName)' sh '$(ProjectDir)/copy_build.sh'"</PostBuildEvent>

0 commit comments

Comments
 (0)