Skip to content

Commit

Permalink
Updated DefaultExecuteStrategy to catch failures in order to throw Bu…
Browse files Browse the repository at this point in the history
…ildException (#115)
  • Loading branch information
roryprimrose committed May 31, 2020
1 parent dfe6ff1 commit ed28386
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 30 deletions.
8 changes: 4 additions & 4 deletions ModelBuilder.UnitTests/DefaultExecuteStrategyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public void BuildThrowsExceptionWhenNotInitialized()

Action action = () => sut.RunTest(type);

action.Should().Throw<InvalidOperationException>();
action.Should().Throw<BuildException>();
}

[Fact]
Expand All @@ -128,7 +128,7 @@ public void BuildTypeThrowsExceptionWhenNotInitialized()

Action action = () => sut.RunTest(type);

action.Should().Throw<InvalidOperationException>();
action.Should().Throw<BuildException>();
}

[Fact]
Expand Down Expand Up @@ -872,7 +872,7 @@ public void CreateThrowsExceptionWhenNotInitialized()

Action action = () => sut.Create(typeof(Person));

action.Should().Throw<InvalidOperationException>();
action.Should().Throw<BuildException>();
}

[Fact]
Expand Down Expand Up @@ -1111,7 +1111,7 @@ public void PopulateThrowsExceptionWhenNotInitialized()

Action action = () => sut.Populate(value);

action.Should().Throw<InvalidOperationException>();
action.Should().Throw<BuildException>();
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@
using ModelBuilder.UnitTests.Models;
using Xunit;

public class ConstructorParameterMatchingTests
public class ConstructorTests
{
[Fact]
public void CreateThrowsExceptionWhenNoPublicConstructorFound()
{
Action action = () => Model.Create<FactoryClass>();

action.Should().Throw<BuildException>();
}

[Fact]
public void DoesNotSetInstanceParameterAssignedToProperty()
{
Expand Down Expand Up @@ -62,5 +70,20 @@ public void PopulatesValueTypePropertyWhenConstructorParameterMatchesDefaultType

model.Id.Should().NotBeEmpty();
}

private class FactoryClass
{
private FactoryClass(Guid value)
{
Value = value;
}

public static FactoryClass Create(Guid value)
{
return new FactoryClass(value);
}

public Guid Value { get; }
}
}
}
78 changes: 53 additions & 25 deletions ModelBuilder/DefaultExecuteStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,40 @@ public virtual object Populate(object instance)
throw new ArgumentNullException(nameof(instance));
}

var capability = _buildProcessor.GetBuildCapability(Configuration, _buildHistory, BuildRequirement.Populate,
instance.GetType());
var type = instance.GetType();

if (capability == null)
try
{
return instance;
}
var capability = _buildProcessor.GetBuildCapability(Configuration, _buildHistory, BuildRequirement.Populate,
instance.GetType());

var type = instance.GetType();
if (capability == null)
{
return instance;
}

var populatedInstance = Populate(capability, instance);
var populatedInstance = Populate(capability, instance);

if (populatedInstance == null)
{
var message = string.Format(CultureInfo.CurrentCulture, "The type '{0}' failed to return a non-null value of type '{1}' after populating its properties.", capability.ImplementedByType.FullName, type.FullName);
if (populatedInstance == null)
{
var message = string.Format(CultureInfo.CurrentCulture, "The type '{0}' failed to return a non-null value of type '{1}' after populating its properties.", capability.ImplementedByType.FullName, type.FullName);

throw new BuildException(message, type, null, null, Log.Output);
}

throw new BuildException(message, type, null, null, Log.Output);
return populatedInstance;
}
catch (BuildException)
{
throw;
}
catch (Exception ex)
{
var message = string.Format(CultureInfo.CurrentCulture, "Failed to populate instance of type '{0}'",
type.FullName);

return populatedInstance;
throw new BuildException(message, ex);
}
}

/// <summary>
Expand All @@ -109,25 +123,39 @@ protected virtual object Build(Type type, params object?[]? args)
throw new ArgumentNullException(nameof(type));
}

BuildCapability? GetCapability() => _buildProcessor.GetBuildCapability(Configuration, BuildChain, BuildRequirement.Create, type);
try
{
BuildCapability? GetCapability() => _buildProcessor.GetBuildCapability(Configuration, BuildChain, BuildRequirement.Create, type);

var instance = Build(
GetCapability,
items => _buildProcessor.Build(this, type, items), type, null, args)!;
var instance = Build(
GetCapability,
items => _buildProcessor.Build(this, type, items), type, null, args)!;

if (instance == null)
{
// The Build method above would have thrown an exception if the build capability could not be identified
var capability = GetCapability()!;
if (instance == null)
{
// The Build method above would have thrown an exception if the build capability could not be identified
var capability = GetCapability()!;

var message = string.Format(CultureInfo.CurrentCulture, "The type '{0}' failed to create a non-null value of type '{1}'", capability.ImplementedByType.FullName, type.FullName);
var message = string.Format(CultureInfo.CurrentCulture, "The type '{0}' failed to create a non-null value of type '{1}'", capability.ImplementedByType.FullName, type.FullName);

throw new BuildException(message, type, null, null, Log.Output);
}
throw new BuildException(message, type, null, null, Log.Output);
}

RunPostBuildActions(instance, type);
RunPostBuildActions(instance, type);

return instance;
return instance;
}
catch (BuildException)
{
throw;
}
catch (Exception ex)
{
var message = string.Format(CultureInfo.CurrentCulture, "Failed to create instance of type '{0}'",
type.FullName);

throw new BuildException(message, ex);
}
}

/// <summary>
Expand Down

0 comments on commit ed28386

Please sign in to comment.