Skip to content

Commit

Permalink
Capture stacktrace of exceptions thrown from async specifications (#522)
Browse files Browse the repository at this point in the history
* Capture stacktrace of exceptions thrown from async specifications

* Update spec projects target to net8.0 as netcoreapp3.1 is no longer available
  • Loading branch information
neilrees authored Jun 23, 2024
1 parent f2ded63 commit 59414c9
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
<TargetFrameworks>net472;net8.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using Example.Exceptions;
using Machine.Specifications.Factories;
using Machine.Specifications.Runner;
using Machine.Specifications.Runner.Impl;
Expand Down Expand Up @@ -70,6 +71,11 @@ class when_running_async_specifications_with_exceptions : RunnerSpecs

It should_have_failures = () =>
results.ShouldEachConformTo(x => !x.Passed);

It should_have_exception_details = () =>
results.ShouldEachConformTo(r => r.Exception.TypeName == nameof(InvalidOperationException) &&
r.Exception.Message == "something went wrong" &&
r.Exception.StackTrace.Contains(typeof(AsyncSpecificationsWithExceptions).FullName));
}

[Subject("Async Delegate Runner")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.ExceptionServices;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -12,7 +13,7 @@ internal class AsyncSynchronizationContext : SynchronizationContext

private int callCount;

private Exception exception;
private ExceptionDispatchInfo exceptionDispatchInfo;

public AsyncSynchronizationContext(SynchronizationContext inner)
{
Expand All @@ -27,7 +28,7 @@ private void Execute(SendOrPostCallback callback, object state)
}
catch (Exception ex)
{
exception = ex;
exceptionDispatchInfo = ExceptionDispatchInfo.Capture(ex);
}
finally
{
Expand Down Expand Up @@ -88,15 +89,15 @@ public override void Send(SendOrPostCallback d, object state)
}
catch (Exception ex)
{
exception = ex;
exceptionDispatchInfo = ExceptionDispatchInfo.Capture(ex);;
}
}

public async Task<Exception> WaitAsync()
public async Task<ExceptionDispatchInfo> WaitAsync()
{
await events.WaitAsync();

return exception;
return exceptionDispatchInfo;
}
}
}
7 changes: 2 additions & 5 deletions src/Machine.Specifications.Core/Runner/Impl/DelegateRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ public void Execute()
{
target.DynamicInvoke(args);

var exception = context.WaitAsync().Result;
var exceptionDispatchInfo = context.WaitAsync().Result;

if (exception != null)
{
throw exception;
}
exceptionDispatchInfo?.Throw();
}
finally
{
Expand Down
4 changes: 4 additions & 0 deletions src/Machine.Specifications.Fixtures/RandomFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,10 @@ public static ValueTask<int> Test()
Cleanup after = async () =>
cleanup_value = await Test();
}
}

namespace Example.Exceptions
{

public class AsyncSpecificationsWithExceptions
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
<TargetFrameworks>net472;net8.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
<TargetFrameworks>net472;net8.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down

0 comments on commit 59414c9

Please sign in to comment.