I maintain a small project that has a web-based search engine for searching through a large collection of documents. The results page is fairly simple, it says something like "Found 341 matches in 645,345 documents" and then displays a list of matches. Easy, right?

Well, last weekend my client called me in a panic and said, "It says it found 341 matches, but where the list of documents is supposed to be, it says 'no matches found!'"

Further investigation revealed that this was only happening on some searches, not all of them. Certain search terms would trigger the bug, but not others. It was quite baffling.

I started playing around with the search code, Dumpering various things to the error log to make sure they looked right. They did. I checked the database query logs to make sure the right queries were being executed. They were. I asked the HTML guy if he had changed any of the templates recently, and he said he hadn't, but I decided to check anyway since he's a liar and often forgets to check in his changes before deploying them.

I noticed that the template contained code like this (simplified for brevity):

Found [% numfound %] matches in [% totaldocs %] documents. <p /> [% IF results.0 %] <ul> [% FOREACH doc IN results %] <li>[% doc %]</li> [% END %] </ul> [% ELSE %] No documents found [% END %]

So what could cause numfound to be populated correctly and yet make results empty, and only some of the time?

Then it hit me like a sack of bricks. results wasn't empty. It's just that sometimes the first element was a false value. Lo and behold, a document had accidentally been entered into the database with a null title. When that document happened to be in the results set, it of course got sorted first, causing the conditional to fail. Changing the conditional to [% IF results.size > 0 %] fixed that problem right up. (And also demonstrated the redundancy of having a separate numfound variable there. Fixed that also.)

And so ended the reign of the most difficult bug ever for that particular project.

So, the moral of the story is: make sure your conditionals are tight. Test the right thing, and only the right thing.


In reply to Keep Those Conditionals Tight by friedo

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.