I am going to recount a recent learning experience I encountered while working on a Rails Project. The ideas I came away with are not Rails specific, however, and are applicable to all software. The learning experienced involved me leaning on third party libraries. This lean later turned into a fall and I realized that third party libraries are to be used for a specific case and only for that case. Dependencies are for what you yourself can not do on your own in a reasonable time period. I learned that we must be careful with the libraries we make use of since their behavior is outside of our control even if we believe to have them pinned down in test.
ActionMailer is a gem most Rails programmers are familiar with. For a story I was completing I needed to email notifications and I knew I was not going to implement a mailing system in a reasonable time period. I then introduced ActionMailer and wrapped the functionality. I had the system under test and I felt pretty confident with what I was using ActionMailer for. My tests were green. The code then went live and I quickly learned that I had made a big mistake. I started receiving ActionMailer generated exceptions. What had happend? I was green when I had committed!
Well, I was green and it was a false positive. ActionMailer has a different set of rules for test and for production. In my case I leaned on ActionMailer and got burnt. I took an array of email addresses and joined them by commas to produce a string to be used as the recipient list of my generated mail. When there were no array entries this produced an empty string. When I sent an empty string to ActionMailer in test it essentially disregards it. Great, I thought, ActionMailer handles my empty email list case! WRONG!
In production an empty string as a recipient list with ActionMailer produces an exception. When the operation is fairly common it produces a lot of exceptions. It was my fault for not narrowing my usage of ActionMailer to the specific cases in which it was actually needed. I instead used it for my empty string case. The moral of story, external dependencies are for specific use cases and nothing more.
No comments:
Post a Comment