views:

286

answers:

5

Following on from a question here got me thinking....

Would it/is it possible that when an application encounters an unhandled exception for this exception object to be serialized and sent to a web service with a db backend. Then, using a utility or even within Visual Studio the exception object could be loaded from the db and inspected??

Would this be at all possible? I guess the first question is whether you can serialize exception objects.

A: 

It's not necessary. Just log the exception.

If you want to log it to a database, go ahead. You can use the Enterprise Library Logging Application Block for this.

John Saunders
Yes you can log the exception to disk but that isn't very useful to a developer when they do not have access to the machine where the exception occurred. The idea is to 1) Inform the developer that an error occurred and 2) Give them as much information that will enable them to track down the problem rather than getting an email saying "Your application just crashed"
Calanus
I said you can log it to a database. The logging block can do that.
John Saunders
Yes but you can only log it to the database if you have direct access to the db in question, which may not alway be the case
Calanus
The DB to be used need not be central. You could store the exception info on a local DB (SQL Server Express, for instance), then regularly copy the data to the central database. The copy would be by a trusted program (maybe SQL Server - I don't know if Mirroring or Log Shipping works with Express), and not by the web application.
John Saunders
+2  A: 

You can serialize exception objects. This is in fact needed to transport an exception object from the server to the client, in the case of an exception being thrown in a web service call. This is why System.Exception has a constructor overload that creates an exception object from serialized data.

Code example for serializing / deserializing exception object:

private static void SerializeException(Exception ex, Stream stream)
{
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(stream, ex);
}

private static Exception DeserializeException(Stream stream)
{
    BinaryFormatter formatter = new BinaryFormatter();
    return (Exception)formatter.Deserialize(stream);
}

// demo code
using (Stream memoryStream = new MemoryStream())
{
    try
    {
        throw new NullReferenceException();
    }
    catch (Exception ex)
    {
        // serialize exception object to stream
        SerializeException(ex, memoryStream);
        memoryStream.Position = 0;
    }
    // create exception object from stream, and print details to the console
    Console.WriteLine(DeserializeException(memoryStream).ToString());
}

That being said, I would probably settle for logging the exception type, message and stack trace somewhere so that I can examine the information.

Fredrik Mörk
Serialize, yes. XML Serialize, not quite so well.
John Saunders
A: 

Yes its possible, in the case where your software is at a remote site you can log it locally and periodically ping back to the "mothership", via your webservice.

It quite an effective way of collecting information about unhandled exception in the wild and resolving them.

If you collect the stack trace its usually good enough to give you a hint where the issue is. However in release builds you won't get any line numbers.

Philip
+1  A: 

Using WCF, this would be an easy task. Implement a custom IErrorHandler to send errors to a logging service. The FaultException<TDetail> class is used by WCF to report errors in a SOAP XML format and it could be sent directly to the logging service.

Ray Vernagus
+1  A: 

Well, there are a number of ways of approaching this. In the past, I have simply done what I would call a super-naive XML serialization, which ammounted to something like

<exception>
    <type></type>
    <Message></Message>
    <StackTrace></StackTrace>
    <innerException></innerException> //this would have the same schema as the root exception
</exception

and simply pass that. I didn't need to deserialize it for what I was doing. I was simply logging the technical part and displaying the message to the user when the webservice failed.

Another option is to simply do a binary serialization to a db table, pass the key to that table over the wire, and rehydrate the exception from binary from the db.

Andy_Vulhop