Make Exception Classes Serializable

A while ago there was a big fuss about correctly writing and using exceptions. Here's one of my pet peeves that I forgot to mention at that time was this: Make your exception classes serializable!

Honestly, I'm sick and tired of having to debug weird SerializationExceptions because an instance of a poorly written exception class crossed an AppDomain boundary. I could understand it if it was an exception class that really was impossible to serialize, but the reality is this is caused mainly by lazyness on the developer's part.

Tip #1: Exceptions are not serializable by default. If you create a custom exception class, it is your responsability to ensure it is serializable.

Tip #2: Marking an exception class with [Serializable] is not enough. System.Exception implements ISerializable, so it forces you to do so as well.

Here's what you should keep in mind when writing an exception class:

  1. Mark the exception type with the [Serializable] attribute.
  2. Add an empty protected serialization constructor that simply delegates to the base class:

protected MyException(SerializationInfo info, StreamingContext ctxt) : base(info, ctxt)

For most exception classes, this will be enough, since most don't actually add new properties and simply rely on the message.

However, if your custom exception class has custom properties, then it MUST override ISerializable.GetObjectData() (and don't forget to call the base one), and you MUST unpack those properties in your serialization constructor.

It's not just about remoting!

What many people seem to forget is that serialization happens in a lot of places without them knowing it. The underlying remoting and serialization mechanisms in .NET (and I don't mean remote object invokation) are the basis for all cross AppDomain calls, even when they are inside the same process boundary.

More and more we see applications and environments where multiple AppDomains are the norm, rather than the exception: VSTO, MMC 3.0, BizTalk, ASP.NET and averything in between (including anything with COM interop in it). And this will grow in the future because using multiple AppDomains is the preffered way of hosting plugins safely and even applications will support extensibility in this fashion in the future.

In each of those cases there's the possibility that your exception might cross an AppDomain boundary, so please make sure it does so gracefully. If you're a library writer (open source or commercial), be aware that the chance that a user might use your library in one of those contexts is always there, so make sure it is a good citizen.

Technorati tags: , , ,

7 Comments

  1. Vineet Dewan

    It would have been nice if you had also shown example of overriding GetObjectData by taking some objects as additional memebers in the custom exception class and also some additional properties.

  2. Jeff S

    I wish the developers of the SharePoint API over at M$ had read this. In working on creating a SharePoint integration for our product I came across weird cases were exceptions I was trying to log through our custom logger were not being logged. I added code to throw errors in the event log and low and behold found that Microsoft.SharePoint.Client.ServerException is not marked as Serializable. That is one that I found, I believe there are some other in the SharePoint API as well. I even posted to MS forums, but all I got as a response was a suggestion to create my own wrapper class to serialize it. Sure, I can do that, but why should I have to, Exceptions should be serializable. I am trying to pass mine through a WCF service.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>