Closed akoken closed 1 year ago
Hi @akoken and thanks for using FusionCache!
This is not a FusionCache bug, but a problem with the ErrorOr library and json serialization, or at least with the json System.Text.Json
serializer.
To be more precise, the ErrorOr<int>
values seem to be serializable but not deserializable.
See this sample:
using ErrorOr;
using System.Text.Json;
ErrorOr<int> e1 = 42;
ErrorOr<int> e2 = Error.NotFound();
Console.WriteLine($"e1: {e1.Value}/{e1.IsError}");
Console.WriteLine($"e2: {e2.Value}/{e2.IsError}");
var j1 = JsonSerializer.Serialize(e1);
var j2 = JsonSerializer.Serialize(e2);
Console.WriteLine("------");
Console.WriteLine($"j1: {j1}");
Console.WriteLine($"j2: {j2}");
e1 = JsonSerializer.Deserialize<ErrorOr<int>>(j1);
e2 = JsonSerializer.Deserialize<ErrorOr<int>>(j2);
Console.WriteLine("------");
Console.WriteLine($"e1: {e1.Value}/{e1.IsError}");
Console.WriteLine($"e2: {e2.Value}/{e2.IsError}");
The output of this is:
e1: 42/False
e2: 0/True
------
j1: {"IsError":false,"Errors":[{"Code":"ErrorOr.NoErrors","Description":"Error list cannot be retrieved from a successful ErrorOr.","Type":1,"NumericType":1}],"ErrorsOrEmptyList":[],"Value":42,"FirstError":{"Code":"ErrorOr.NoFirstError","Description":"First error cannot be retrieved from a successful ErrorOr.","Type":1,"NumericType":1}}
j2: {"IsError":true,"Errors":[{"Code":"General.NotFound","Description":"A \u0027Not Found\u0027 error has occurred.","Type":4,"NumericType":4}],"ErrorsOrEmptyList":[{"Code":"General.NotFound","Description":"A \u0027Not Found\u0027 error has occurred.","Type":4,"NumericType":4}],"Value":0,"FirstError":{"Code":"General.NotFound","Description":"A \u0027Not Found\u0027 error has occurred.","Type":4,"NumericType":4}}
------
e1: 0/False
e2: 0/False
As you can see, the serialized json seems to be there, but when deserializing it doesn't "come back" correctly.
I assume you can solve this by using a custom converter.
Regarding the fact that FusionCache is not throwing serialization errors: that is because, as you can see in the sample above, the System.Text.Json
serializer is not throwing an error, but simply creating an ErrorOr0
and false
), so FusionCache cannot possibly know that something went "wrong".
Let me know if you need more help.
Hope this helps!
Thanks for the quick and detailed reply @jodydonetti.
As you can see, the serialized json seems to be there, but when deserializing it doesn't "come back" correctly.
To be honest, I did not expect that :)
I assume you can solve this by using a custom converter.
Yes, that could work!
Regarding the fact that FusionCache is not throwing serialization errors: that is because, as you can see in the sample above, the
System.Text.Json
serializer is not throwing an error, but simply creating an ErrorOr instance with default values (0
andfalse
), so FusionCache cannot possibly know that something went "wrong".I'm not sure, but
record struct
can cause it. I'll dig deeper into ErrorOr source code.
Thank you for taking the time!
Hi again @jodydonetti,
I'm experiencing a problem with the GetOrSetAsync method and can't figure out what's causing it. I personally don't like throwing exception in my code. That's why I prefer ErrorOr package to be able to use discriminated union. But the problem is that Fusion Cache returns null if I use ErrorOr type. That appears to be a serialization issue, however there is no serialization error log in Fusion Cache. Is there something I'm missing?
Steps to reproduce:
The first endpoint loads data from distributed to memory and then returns it successfully. The second one loads data from distributed to memory successfully but returns null.
You may find the related code here to reproduce.
Versions I've encountered this issue on:
Additional context There is a catch here. The one with the ErrorOr type keeps working until I stop the application for the first time.