Closed LorneCash closed 7 months ago
will this work for you
[Fact]
public async Task DisposedTaskCanceledException()
{
var cancel = new CancelSource();
cancel.Cancel();
var test = new TaskCanceledException("test", null, cancel.Token);
cancel.Dispose();
await Verify(test)
.IgnoreMembersThatThrow<ObjectDisposedException>();
}
or globally
[ModuleInitializer]
public static void Init() =>
VerifierSettings
.IgnoreMembersThatThrow<ObjectDisposedException>();
Amazing, .IgnoreMembersThatThrow
I can't believe I missed that. Thank you so much!
here is the doco https://github.com/VerifyTests/Verify/blob/main/docs/serializer-settings.md#members-that-throw
I can't believe I missed that.
please dont hesitate to ask questions or raise issues for (what u think are) missing apis. it is a large surface area, and i am happy to point to the relevant docs.
and i am on twitter @SimonCropp and mastodon simoncropp@hachyderm.io if u want a more adhoc conversation
I feel like it would be slightly better if it said something like:
WaitHandle: <Disposed>
Or:
WaitHandle: <ObjectDisposedException>
instead of:
WaitHandle: null
But I'm not complaining!
I'm also slightly curious if you'd want to look into fixing this specific case so that it would not require using .IgnoreMembersThatThrow<T>()
due to the fact that it throws from the .Verify()
method, but that's a design decision for you and really makes no difference to me.
yeah those are good suggestions. i will look into them
I created a classes derived from Argon.DefaultContractResolver
and Argon.IValueProvider
.
using System.Reflection;
using Argon;
public class VerifyReceivedContractResolver : DefaultContractResolver
{
/// <inheritdoc />
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (property is { Ignored: false, ValueProvider: { } valueProvider })
{
property.ValueProvider = new SafeValueProvider(valueProvider);
}
return property;
}
private class SafeValueProvider : IValueProvider
{
private readonly IValueProvider UnderlyingValueProvider;
public SafeValueProvider(IValueProvider underlyingValueProvider) => UnderlyingValueProvider = underlyingValueProvider;
public void SetValue(object target, object? value) => UnderlyingValueProvider.SetValue(target, value);
public object? GetValue(object target)
{
try
{
return UnderlyingValueProvider.GetValue(target);
}
catch (Exception ex)
{
var message = $"[{ex.GetType().FullName}]{ex.Message}";
while (ex.InnerException is { } exInner)
{
message += $" ==> [{exInner.GetType().FullName}]{exInner.Message}";
ex = exInner;
}
return message;
}
}
}
}
This works really well for me because it's not specific to CancellationToken
, WaitHandle
, or any specific Exception
type at all. It (the serialization) just works and then I can decide to ignore or scurb as I please.
Here's what the output looks like:
CancellationToken: {
IsCancellationRequested: true,
CanBeCanceled: true,
WaitHandle: [Argon.JsonSerializationException]Error getting value from 'WaitHandle' on 'System.Threading.CancellationToken'. ==> [System.ObjectDisposedException]The CancellationTokenSource has been disposed.
},
@SimonCropp With 23.5.1 (your latest update), it seems that the CanBeCanceled
property of TaskCanceledException
is just called Token
, not sure if that was intentional but it confused me for a sec.
I'm also noticing that when the token is disposed WaitHandle
is missing. I'm sure that one was intentional. Personally I prefer it my way with the error message but your way makes sense too. 👍
And lastly I now understand that my VerifyReceivedContractResolver
was really a fix for Argon rather than Verify so I get why you might not want to do that.
Thanks again for all your work on this amazing project!
can u try 23.5.2
Beautiful! 💯
This Unit test runs fine:
And I get this in the .received.txt:
But if I try to run the same test after disposing the cancellation token like this:
Verify
throws thisException
: Argon.JsonSerializationException: Error getting value from 'WaitHandle' on 'System.Threading.CancellationToken'. ---> System.ObjectDisposedException: The CancellationTokenSource has been disposed.Obviously I'm not actually trying to Verify this simple example, or I would just not dispose the
CancellationTokenSource
. However, since disposing them is recommended it's not surprising that this situation would come up sooner or later.I'd love to see the output something like this:
But omitting the
WaitHandle
property would me more than acceptable also.If there's an easy workaround that I've missed, please forgive my ignorance, and help me out by pointing me in the right direction.