Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabled ReduxDevTools throw NotSupportedException upon serialization of CancellationToken #353

Open
Eagle3386 opened this issue Jun 1, 2023 · 3 comments

Comments

@Eagle3386
Copy link

My used UI library, MudBlazor, has a MudAutoComplete<T> component that supports both, querying of a remote service upon input via its SearchFuncWithCancel attribute/property as well as cancellation of such queries via passing its CancellationToken down the pipeline.

While BlazorState supports consumption of such token just like passing it on to an IAction, e. g.:

await Mediator.Send(new MyState.QueryAction {, Token = token }, token);

its ReduxDevTools throw the aforementioned exception due to CancellationToken's WaitHandle which itself has a property named Handle that is of type System.IntPtr:

[BlazorState.Pipeline.ReduxDevTools.ReduxDevToolsBehavior`2[
  [MyApp.Features.Search.SearchState+ReadAction, …],
  [MediatR.Unit, MediatR.Contracts, Version=2.0.1.0, …]]]
Exception:
  System.NotSupportedException: Serialization and deserialization of 'System.IntPtr' instances are not supported.
  Path: $.Payload.Token.WaitHandle.Handle.
 ---> System.NotSupportedException:
        Serialization and deserialization of 'System.IntPtr' instances are not supported.
   at System.Text.Json.Serialization.Converters.UnsupportedTypeConverter`1[[…]]
            .Write(Utf8JsonWriter writer, IntPtr value, JsonSerializerOptions options)

   // … Left out for brevity …

   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(WriteStack& state, NotSupportedException ex)

   // … Left out for brevity …

   at System.Text.Json.JsonSerializer.Serialize[Object[]](Object[] value, JsonSerializerOptions options)
   at Microsoft.JSInterop.JSRuntime.InvokeAsync[Object](
     Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args)
   at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__16`1[[…]].MoveNext()
   at BlazorState.Pipeline.ReduxDevTools.ReduxDevToolsInterop.<DispatchAsync>d__10`1[[…]].MoveNext()
   at BlazorState.Pipeline.ReduxDevTools.ReduxDevToolsBehavior`2.<Handle>d__6[
     [MyApp.Features.Search.SearchState.ReadAction, …],
     [MediatR.Unit, MediatR.Contracts, Version=2.0.1.0, …]].MoveNext()

But that's totally fine, because that's the expected behavior since .NET 5 as well as the fact that you (hopefully) can't deserialize it back into an IntPtr.
Though, IMHO, BlazorState's ReduxDevTools support should catch this exception in order to allow for proper app debugging - currently, that's only possible with ReduxDevTools enabled and adding the [JsonIgnore] attribute to properties of types like CancellationToken:

public class ReadAction : IAction
{
  // … Left out for brevity …

  [JsonIgnore]
  public CancellationToken Token { get; init; }
}
@StevenTCramer
Copy link
Collaborator

You are doing it correctly with the JsonIgnore. Why would you want this CancellationToken serialized and sent to ReduxDevTools? Is there something you want to view in it?

@mrpmorris
Copy link

Does it fix the problem if you store it as a field instead of a property?

public required CancellationToken Token;

@Eagle3386
Copy link
Author

You are doing it correctly with the JsonIgnore. Why would you want this CancellationToken serialized and sent to ReduxDevTools? Is there something you want to view in it?

Although JsonIgnore helps to "get the job done", IMHO "doing it correctly" would require BLazerState to either prevent the exception by ignoring any unsupported type from the start or at least catch this type of exception for the whole app not to break - whether ReduxDevTools is open & used within the browser or not.

Besides, it would be the "full dev experience" just to be able to inspect all supported properties within ReduxDevTools, no matter if it's CancellationToken or some other object containing an IntPtr (or one of its properties's type).

Does it fix the problem if you store it as a field instead of a property?

Yes, but I'm no fan of fields at all - wherever possible, I use properties throughout my code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants