Search code examples
f#websharper

Websharper can't deserialize union type


I have the following client code:

|>! OnClick (fun _ _ -> Server.CreateBug input.Value |> Server.SendCommand)

Here's the type and server code:

type Command =
    | CreateBug of string
    | Query of Query * AsyncReplyChannel<string>

[<Rpc>]
let SendCommand cmd =
    dispatcher.Post cmd

The client can serialize this to: [{"$":0,"$0":"test"}]

But then I get the following log error when debugging:

WebSharper.Web Error: 0 : Failed to execute a remote call. Failed to get JSON deserializer for: ClientReferral.Server+Command[]

WebSharper Error: 0 : Failed to execute a remote call. Failed to get JSON deserializer for: ClientReferral.Server+Command[]

This code is rather trivial and there doesn't seem to be anything indicating it wouldn't work in the WebSharper manual. I even remember using it like that, so I don't know what's wrong.

Edit: This is the definition of Query:

type Query =
    | GetBugs
    | GetBugInfo of int

Solution

  • the fact that the error is happening at runtime and not at compile time is definitely a bug, I will try to reproduce and fix on Monday.

    Technically, since AsyncReplyChannel<'T> does not have a default constructor WebSharper cannot construct a deserializer for it.

    Looking at the higher level, I cannot understand your intent. Why send a function-isomorphic type over RPC?

    Moreover, this:

    |>! OnClick (fun _ _ -> Server.CreateBug input.Value |> Server.SendCommand)
    

    This looks to me like an attempt to construct an object on the server, then gratuitously send it to the client and back, and then do something with it - is this right? I assume Server.* functions execute on the server. If so, it must be refactored to a single call:

    |>! OnClick (fun _ _ -> Server.SendBugCommand input.Value)
    
    [<Rpc>]
    let SendBugCommand x =
        CreateBug x
        |> SendCommand