Orleans: Unable to serialize new .NET package exceptions

Created on 17 Dec 2016  路  7Comments  路  Source: dotnet/orleans

Packages I depend on have begun migrating to what I think is "netstandard"? In any case, they now require tiny little micro-packages for each .NET namespace. This would be merely annoying, except the latest versions of these namespace level packages contain types which are no longer [Serializable].

It appears that many exceptions Orleans used to successfully relay from grains to my client applications can no longer be serialized out of the box, and it's not clear how I should add support for serializing them.

Here's a test project demonstrating my problem, and two now unserializable exception types that have been appearing in my logs: https://github.com/realartists/orleans-serialization-failure

I've tried KnownType, KnownAssembly, and GenerateSerializer attributes without success. KnownType and KnownAssembly silently fail to generate a serializer, only failing at runtime, and GenerateSerializer fails during build.

I tried adding a custom serializer for Exception, but it's never called for derived types, even as a fallback.

I must be missing something obvious.

I'm using the 1.3.1 nuget package. The specific exceptions I'm seeing are both Orleans.Runtime.OrleansException:

_No copier found for object of type System.Net.Http.HttpRequestException. Perhaps you need to mark it [Serializable] or define a custom serializer for it?_

Orleans.Serialization.SerializationManager.DeepCopierHelper(Type t, Object original):640
 Orleans.Serialization.SerializationManager.DeepCopyInner(Object original):106
 Orleans.Serialization.SerializationManager.DeepCopy(Object original):41
 Orleans.Runtime.InsideRuntimeClient.SafeSendExceptionResponse(Message message, Exception ex):0
... [My grain code]

_No copier found for object of type System.Net.Http.UnsupportedMediaTypeException. Perhaps you need to mark it [Serializable] or define a custom serializer for it?_

Orleans.Serialization.SerializationManager.DeepCopierHelper(Type t, Object original):640
 Orleans.Serialization.SerializationManager.DeepCopyInner(Object original):106
 Orleans.Serialization.SerializationManager.DeepCopy(Object original):41
 Orleans.Runtime.InsideRuntimeClient.SafeSendExceptionResponse(Message message, Exception ex):0

Most helpful comment

Oh, wow, you're way ahead of me. #2310 describes exactly the behavior I'd like, though if it helps at all I'll never use round tripping. As long as I have enough information to get a meaningful report from Raygun or Application Insights I'm happy.

I guess count this as a from-the-field 馃憤 for #2310.

Thanks!

All 7 comments

I believe this is already resolved in master via #2162 (has to be explicitly configured for now). Will be included in v1.4.0. Can you build latest source and try with that?

Oh, great. I'll try that out and let you know. Thanks!

You can enable it like so, @kogir:
C# config.Globals.FallbackSerializationProvider = typeof(ILBasedSerializer).GetTypeInfo();

Thanks again for the pointers (and all the new work for 1.4.0)!

I updated my example project to contain a separate silo and client, and used Orleans 1.4.0 packages I built locally from master.

The results are mixed. Adding ILBasedSerializer as the FallbackSerializationProvider solves the silo serialization problem. Which is great - the silo sends the HttpRequestException to the client. But there's a catch - the client doesn't have the assembly containing HttpRequestException, and can't deserialize it.

I think this will be a new and common issue with .NET Core and .NET Standard. Previously, the client machine had to have the .NET Framework, so even if the client application itself didn't ship a copy of the assembly, standard ones (from System.Net, for example) could be loaded from the machine GAC.

With this new tiny package approach, it will be very common for clients not to have any assemblies they're not directly using. While requiring clients to have the assemblies for the grain interface is fine, I don't think it's reasonable to expect them to have every assembly used by every grain implementation.

I'm not really sure what the right course of action is. I'd be happy with Orleans doing something special when serializing Exception and its derived classes. On the client side it's enough for me to know:

  1. That an exception occurred
  2. What the message was
  3. The stack trace

Basically all the core properties on the Exception base class. In fact, deserializing the HttpRequestException as just a basic Exception would be preferable to failing outright.

I'm not sure whether or not Orleans should officially support such behavior, but if I wanted to implement it, can you point me to the right place to start? Would creating my own ILBasedSerializer based FallbackSerializationProvider be the correct approach?

I've attached the logs from my test run where the client is unable to locate the System.Net.Http assembly.
silo.txt
client.txt

@kogir good suggestion! In a way, it is out of scope, but we can add support to it simply because it makes people's lives easier (which is the whole point, right?).

We have #2310 opened for this and I have a prototype implementation which I can clean up

EDIT: here's a commit where I was working on it: https://github.com/dotnet/orleans/commit/e18403a2456498db0f64339e0a3861279289bdc2
You can see the ExceptionSerializer there. I wasn't satisfied with it at the time because it wasn't as isolated from the rest of the serialization system as I would have liked

Oh, wow, you're way ahead of me. #2310 describes exactly the behavior I'd like, though if it helps at all I'll never use round tripping. As long as I have enough information to get a meaningful report from Raygun or Application Insights I'm happy.

I guess count this as a from-the-field 馃憤 for #2310.

Thanks!

@kogir, I've implemented this in #2633. Hopefully it works for you

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DixonDs picture DixonDs  路  4Comments

scharada picture scharada  路  3Comments

luciobemquerer picture luciobemquerer  路  4Comments

Vlad-Stryapko picture Vlad-Stryapko  路  3Comments

turowicz picture turowicz  路  3Comments