Calling Encode.Auto.toString throws System.Exception JS only
WallaceKelly opened this issue · comments
Am I doing something wrong? Or is this a bug?
Steps to Reproduce
- Run
dotnet new console --language F#
- Run
dotnet add package Thoth.Json
- Edit
Program.fs
as shown below. - Run
dotnet run
Project file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>thoth_test</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Thoth.Json" Version="7.0.0" />
</ItemGroup>
</Project>
Program.fs
[<CLIMutable>]
type MyRecord = { Name: string; Age: int }
let myRecord = { Name = "Wallace"; Age = 42 }
let json = Thoth.Json.Encode.Auto.toString(0, myRecord)
printfn $"{json}"
Expected Result
Successfully prints a JSON version of my record value.
Actual Result
Unhandled exception. System.Exception: JS only
at Fable.Core.JsInterop.op_BangBang[a,T](a x)
at Thoth.Json.Encode.mapping@1-1(CaseStrategy caseStrategy, Boolean skipNullField, FSharpMap`2 extra, PropertyInfo fi)
at Thoth.Json.Encode.autoEncodeRecordsAndUnions(FSharpMap`2 extra, CaseStrategy caseStrategy, Boolean skipNullField, Type t)
at Thoth.Json.Encode.autoEncoder(FSharpMap`2 extra, CaseStrategy caseStrategy, Boolean skipNullField, Type t)
at <StartupCode$thoth-test>.$Program.main@() in C:\temp\thoth-test\Program.fs:line 10
System Info
Windows 10
> dotnet --list-sdks
3.1.416 [C:\Program Files\dotnet\sdk]
5.0.210 [C:\Program Files\dotnet\sdk]
5.0.402 [C:\Program Files\dotnet\sdk]
5.0.404 [C:\Program Files\dotnet\sdk]
6.0.101 [C:\Program Files\dotnet\sdk]
Hello @WallaceKelly,
You are trying to use run the Fable version of Thoth.Json against .NET.
If you want to use Thoth.Json API on .NET for now it is provided using another package called Thoth.Json.Net.
More info available here: https://thoth-org.github.io/Thoth.Json/documentation/concept/fable-and-dotnet-support.html
Thank you, @MangelMaxime. I should have figured that out on my own. 🙄
This works, of course:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="thoth.json.net" Version="8.0.0" />
</ItemGroup>
</Project>
[<CLIMutable>]
type MyRecord = { Name: string; Age: int }
let myRecord = { Name = "Wallace"; Age = 42 }
let json = Thoth.Json.Net.Encode.Auto.toString(0, myRecord)
printfn $"{json}"
Your welcome.
The error is not really explicit I will see if we can make it more explicit in Fable.
Having 2 packages depending on the runtime is not ideal, there are plan in the future to have a single package working everywhere. That should avoid similar problem in the future.
I was just burned by this for 20 mins. Even changing the message from "JS only" to "- you need Thoth.Json.Net for dotnet" would be a big help.
@daz10000 Thoth.Json is not the one generating the exception it done by Fable.Core package.
Looking at the definition of the function, the error message should be:
You've hit dummy code used for Fable bindings. This probably means you're compiling Fable code to .NET by mistake, please check.
The problem is that Thoth.Json requires Fable.Core >= 3.1.6 when the improved error message was introduced in 3.6.2.
I released a new version which force Fable.Core to be at least at version 3.6.2.
Thanks for the quick reply, and that all makes sense. For what it's worth, I wasn't anywhere near Fable at the time (didn't suspect I was accidentally using a Fable library). That's what made it so confusing. This ticket was the only clue to error message. I was troubleshooting some Thoth encoding in fsi
with something like this
#r "nuget:Thoth.Json"
open Thoth.Json
let v = 123
let s : string = Encode.Auto.toString v
I see the new error message now! I still think it's slightly misleading. I'm not compiling fable code to .net - I'm binding .net code to a fable library by accident. That might be a subtle distinction, but Thoth.Json
doesn't scream Fable library .. I have no fable in this particular project so brain didn't even go there.
System.Exception: You've hit dummy code used for Fable bindings. This probably means you're compiling Fable code to .NET by mistake, please check.
at Fable.Core.JsInterop.op_BangBang[a,T](a x)
at <StartupCode$FSI_0002>.$FSI_0002.main@() in C:\XXX\t.fsx:line 5
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
Stopped due to error
The way I see to improve this error would be to do a try / catch and then check the error message in order to rewrite it.
But I don't think that a great solution. The elegant solution will come with Thoth.Json 11+ which is a rewrite of the library to support both Fable and .NET at the same time. So people will not have to worry about such things anymore in the future.