runtime: Serializing exceptions in CoreCLR

It has recently come to my attention that CoreCLR has eliminated ISerializable. While I believe that this is a move in the right direction, it seems to have also removed the only way possible to correctly serialize exceptions in .NET. Serialization of exceptions is tricky, because they are objects which encapsulate two types of data:

  1. Data defined at construction time, such as Message, InnerException or any other fields defined by the particular exception implementation.
  2. Data appended by the runtime, such as StackTrace. Importantly, this is data that cannot be modified by the user without resorting to reflection.

A correct exception serialization should carry along both types of data. This is very important in distributed frameworks such as akka.net, mbrace and I would imagine Orleans too. So my question here is, what will CoreCLR be offering as a replacement scheme for serializing exceptions?

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 3
  • Comments: 37 (25 by maintainers)

Most upvoted comments

@mikedn This is in the context of cloud-scale distributed programming systems such as AkkaDotNet and MBrace (http://mbrace.io). Please familiarize yourself with these systems, check out this video for example. https://channel9.msdn.com/Events/dotnetConf/2015/The-F-Path-to-Data-Scripting-Nirvana

In this kind of system, .NET code gets distributed and run over clusters of hundreds or thousands of machines. These represent a very important use of JVM and .NET-like systems and are some of the most promising applications of .NET in the cloud. They are not the kind of system where you connect your debugger to each of 10,000 .NET instances, something which obviously won’t scale.

In this context, it is entirely normal to distribute code to other machines and to marshal results (including exceptions) back to host processes. This is normal on the JVM and normal for .NET Framework. So yes, the use case is valid.

Pardon my ignorance, but why are people focusing on the ISerializable abstraction (etc) when what’s actually wanted here, very specifically, is a way to:

  1. Convert an Exception (and sub-classes thereof) into a streamable form (e.g. string or byte[]), and
  2. Create an Exception from that streamable form, potentially on another system.

Exceptions are such a specialized type within .NET that providing some way of working with them like this seems eminently sensible, especially in the context of distributed systems, and it shouldn’t be blocked just because ISerializable is a horrible abstraction in other contexts. And an Exception-specific solution would probably offer better performance, wouldn’t it?

Relating to other threads, the same might be true for lambda…

I commented in https://github.com/dotnet/corefx/issues/7938 that

FormatterServices.GetUninitializedObject() is absolutely necessary for Orleans-generated serializers. Without it we’ll be entirely broken.

MBrace certainly benefits from the stack trace. If I write

let f1 () = ... raise exception ...

let f2 () = ... f1 () ...

cloud { f2() } |> cluster.Run

Then we expect an exception raised on the client and a stacktrace with f1 and f2. To be honest it’s probably the most important part of the exception details we need 😃

Can I ask what the motivation for excluding certain exception types is? For distributed frameworks such as mbrace, akka.net and orleans (whose key people have commented in this very thread) this is is crippling.

@RogerAlsing MS is a cloud company now. I assume supporting the major cloud programming frameworks is no. 1 priority. Since all maintainers of the big .NET cloud frameworks already expressed big interest here they are surely already working on this.