Skip to content

Commit

Permalink
TypeResolver: log ReflectionTypeLoadException with more details (#8)
Browse files Browse the repository at this point in the history
* Log ReflectionTypeLoadException when loading types by base type or interface.
  • Loading branch information
tusmester authored Feb 24, 2017
1 parent 0563589 commit fea8799
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/SenseNet.Tools.Tests/SenseNet.Tools.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<Compile Include="SnTraceTestClass.cs" />
<Compile Include="SnTraceTests.cs" />
<Compile Include="SnLogTests.cs" />
<Compile Include="TypeResolverTests.cs" />
<Compile Include="UtilityTests.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
65 changes: 65 additions & 0 deletions src/SenseNet.Tools.Tests/TypeResolverTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace SenseNet.Tools.Tests
{
#region Test classes

internal interface ITestInterface
{
}

internal class BaseClass
{
}

internal class DerivedClass1 : BaseClass
{
}
internal class DerivedClass11 : DerivedClass1, ITestInterface
{
}
internal class IndependentClass1 : ITestInterface
{
}

#endregion

[TestClass]
public class TypeResolverTests
{
[TestMethod]
public void TypeResolver_GetType()
{
var t = TypeResolver.GetType("SenseNet.Tools.TypeResolver");
Assert.IsNotNull(t);
}

[TestMethod]
public void TypeResolver_GetTypesByBaseType()
{
var types = TypeResolver.GetTypesByBaseType(typeof(BaseClass));

Assert.AreEqual(2, types.Length);
Assert.IsTrue(types.Any(t => t.Name == "DerivedClass1"));
Assert.IsTrue(types.Any(t => t.Name == "DerivedClass11"));
}
[TestMethod]
public void TypeResolver_GetTypesByInterface()
{
var types = TypeResolver.GetTypesByInterface(typeof(ITestInterface));

Assert.AreEqual(2, types.Length);
Assert.IsTrue(types.Any(t => t.Name == "DerivedClass11"));
Assert.IsTrue(types.Any(t => t.Name == "IndependentClass1"));
}

[TestMethod]
[ExpectedException(typeof(TypeNotFoundException))]
public void TypeResolver_Error_GetType()
{
var t = TypeResolver.GetType("UnknownType");
Assert.IsNotNull(t);
}
}
}
31 changes: 22 additions & 9 deletions src/SenseNet.Tools/Tools/TypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,18 @@ public static Type[] GetTypesByInterface(Type interfaceType)
list.AddRange(asm.GetTypes().Where(type =>
type.GetInterfaces().Any(interf => interf == interfaceType)));
}
catch (Exception e)
catch (ReflectionTypeLoadException e)
{
if (!IgnorableException(e))
{
LogTypeLoadException(e, asm.FullName);
throw;
}
}
catch (Exception e)
{
if (!IgnorableException(e))
throw TypeDiscoveryError(e, null, asm);
}
}
temp = list.ToArray();
Expand Down Expand Up @@ -300,17 +308,13 @@ public static Type[] GetTypesByBaseType(Type baseType)
}
}
}
catch (ReflectionTypeLoadException rtle)
catch (ReflectionTypeLoadException e)
{
SnLog.WriteError(rtle.ToString(), properties: new Dictionary<string, object> { { "Assembly", asm.FullName } });

// Logging each exception
foreach (var exc in rtle.LoaderExceptions)
if (!IgnorableException(e))
{
SnLog.WriteError(exc);
LogTypeLoadException(e, asm.FullName);
throw;
}

throw;
}
catch (Exception e)
{
Expand All @@ -331,6 +335,15 @@ public static Type[] GetTypesByBaseType(Type baseType)
return result;
}

private static void LogTypeLoadException(ReflectionTypeLoadException rtle, string assemblyName = null)
{
SnLog.WriteError(rtle.ToString(), properties: new Dictionary<string, object> { { "Assembly", assemblyName ?? "unknown" } });

foreach (var exc in rtle.LoaderExceptions)
{
SnLog.WriteError(exc);
}
}
private static bool IgnorableException(Exception e)
{
if (!Debugger.IsAttached)
Expand Down

0 comments on commit fea8799

Please sign in to comment.