📣Postmark has been acquired by ActiveCampaign
x

[OSS Friday] Upgrading to the Hoptoad v2 API

Hoptoad

We have been using Hoptoad for our email delivery service , Postmark, and have been extremely happy with it. We are able to get all sorts of feedback on how our app is doing, often being able to fix an issue before a customer actually reports it. At first glance Hoptoad looks just like a regular error logger attached to an SMTP endpoint, but you see the huge difference when you start using the app. Yes, you get error notifications over email, but you also get reports about the different types of errors you are getting, errors that happen only in a specific environment (dev, staging, production), and errors popping up after a specific deployment you rolled out. Cool stuff. Imagine how bad would be to work without all that data to support you.

But this is exactly what happened when Hoptoad introduced v2 of their API and phased the current API out. The guys provided an excellent Ruby client library that just worked. Unfortunately Postmark's delivery engine is built in C# and Microsoft.NET. Hopsharp, the .NET client library stayed at the v1 API. I guess there are not that many .NET developers using Hoptoad over there, and Ken Robertson, the Hopsharp author, must have a lot more interesting projects on his hands. So, with the code being open sourced and hosted on GitHub it was pretty simple for me to do something about that problem. At Wildbit we are trying to establish a tradition of allocating a Friday each month for open source work, and that is how Hopsharp became my first OSS Friday project.

The Solution

Last Friday I rolled up my sleeves, forked the project and started hacking. The Hoptoad API has changed a lot. V1 used a JSON-based protocol, while v2 uses XML. The Hoptoad guys were kind enough to provide an XSD schema, so that you could validate your data before sending it to them (and before complaining to their support folks that "It doesn't work"). Here is what you need to provide as the bare minimum:

  • An error notice with some basic data: API version and an API key;
  • The error (duh!) with a class, message and backtrace;
  • Notifier details: information about your library like name, project URL, version;
  • The server environment: the app project root and the environment name

My XML skills with .NET were a bit rusty, but I could quickly whip up an object model that I could handle to the XML serializer and have it spew the correct XML back at me. I kept throwing that at the XML schema validator until it got accepted, and that was it. I pulled all external data like environment names, project settings and paths and Hoptoad parameters to a separate class, and set up a builder object to orchestrate all creation and object composition. Being a spoiled xUnit.net user, I felt some pain writing NUnit tests, but I got over that quickly. Today, finishing my work, I was able to send my first v2 error notice to Hoptoad.

The End Result

Overall I feel like I rewrote most of the project. Probably the only thing that is left from the original code is the part that crafts the actual HTTP request to the Hoptoad servers. My efforts are by no means over, though. Here's what's left:

  • Hoptoad, being targeted at mostly web apps, allows you to submit details about the current HTTP request like URL, controller and action names, request and session parameters and CGI data (server variables?).
  • The error reporting part needs more testing and stabilization.
  • Building the error backtrace that contains the file and line number for all stack frames doesn't always work. I guess one needs to deploy the debug symbols (PDB files) for the respective assemblies to get that working. We default to class name for file name and IL instruction offset for line number when that info is not available. Maybe we can do better here.

I'll probably keep hacking at the code when I get some more free time. After all I want to get rid of my current log4net SMTP error loggers and get back to using Hoptoad ASAP. I'll post an update when I'm done with sending the request details and when I feel the library is stable enough for me to use in Postmark. The code is available here. You're welcome to play with the code, send bug reports and, of course, patches.