Skip to content

Instantly share code, notes, and snippets.

@mnebes
Last active February 3, 2023 14:58
Show Gist options
  • Save mnebes/12e51348d76440c5106202315494272a to your computer and use it in GitHub Desktop.
Save mnebes/12e51348d76440c5106202315494272a to your computer and use it in GitHub Desktop.
Thoth crash repro
#r "nuget: Thoth.Json.Net"
open Thoth.Json.Net
type User =
{
Name : string
Age : int
}
module User =
let decode : Decoder<User> =
Decode.object (fun get ->
{
Name = get.Required.Field "name" Decode.string
Age = get.Required.Field "age" Decode.int
}
)
type Post =
{
Title : string
Abstract : string
}
module Post =
let decode : Decoder<Post> =
Decode.object (fun get ->
// accessing a value and doing something with it
let abst = get.Required.Field "abstract" Decode.string
abst |> Seq.head |> printfn "%A"
{
Title = get.Required.Field "title" Decode.string
Abstract = abst
}
)
type Data =
{
User : User
Post : Post option
}
module Data =
// Get both structures and decode them with their own decoder accordingly
let decoder : Decoder<Data> =
Decode.object (fun get ->
{
User = get.Required.Field "user" User.decode
Post = get.Optional.Field "post" Post.decode
}
)
let json = """
{
"data": {
"user": {
"name": "Triss Merigold",
"age": 42
},
"post": null
}
}
"""
Decode.fromString
(Decode.field "data" Data.decoder)
json
// Prints:
(*
> Decode.fromString
- (Decode.field "data" Data.decoder)
- json;;
System.ArgumentNullException: Value cannot be null. (Parameter 'source')
at Microsoft.FSharp.Collections.SeqModule.Head[T](IEnumerable`1 source) in D:\a\_work\1\s\src\FSharp.Core\seq.fs:line 1647
at FSI_0007.PostModule.decode@116-12.Invoke(IGetters get) in ..scratchpad.fsx:line 118
at Thoth.Json.Net.Decode.object[value](FSharpFunc`2 builder, String path, JToken v)
at Thoth.Json.Net.Decode.decodeMaybeNull[T](String path, FSharpFunc`2 decoder, JToken value)
at Thoth.Json.Net.Decode.optional[value](String fieldName, FSharpFunc`2 decoder, String path, JToken value)
at Thoth.Json.Net.Decode.-ctor@806-4.Invoke(String path, JToken value)
at Thoth.Json.Net.Decode.unwrapWith[T](List`1 errors, String path, FSharpFunc`2 decoder, JToken value)
at Thoth.Json.Net.Decode.-ctor@804-3.Thoth.Json.Net.Decode.IOptionalGetter.Field[a](String fieldName, FSharpFunc`2 decoder)
at FSI_0007.DataModule.decoder@136-2.Invoke(IGetters get) in ..scratchpad.fsx:line 137
at Thoth.Json.Net.Decode.object[value](FSharpFunc`2 builder, String path, JToken v)
at Thoth.Json.Net.Decode.fromValue[T](String path, FSharpFunc`2 decoder, JToken value)
at Thoth.Json.Net.Decode.fromString[T](FSharpFunc`2 decoder, String value)
at <StartupCode$FSI_0008>.$FSI_0008.main@() in ..scratchpad.fsx:line 155
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
*)
// If the value is missing, everything works fine.
let json = """
{
"data": {
"user": {
"name": "Triss Merigold",
"age": 42
}
}
}
"""
(*
> Decode.fromString
- (Decode.field "data" Data.decoder)
- json;;
val it: Result<Data,string> = Ok { User = { Name = "Triss Merigold"
Age = 42 }
Post = None }
*)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment