Learned a lesson the hard way this week. debugging a problem where a code running against the
property of a mail file with over 7000 folders couldn’t locate certain folders even though the interface clearly showed the folders as being there.
The ultimate cause was as simple as stupid: The code that ran against the Database.views property used the (undocumented) function
folder = getParentFolder()
to ask the user to select a folder. This function shows the user a folder select dialog and returns the selected folders as an array.
The users would select folders but for some reason the subsequent code retrieving the selected folders from the database.views wouldn’t always find them.
After some debugging the cause turned out to be that the folder names that the
Returned does a
on the selected folder names before putting it into the array. Problem was however that on creation of the folder (which was not being done manually but through a script in which the user was prompted for a folder name) the user sometimes added leading, trailing or double spaces in the name.
On normal (manual) folder creation, folder names are automatically trimmed to remove obsolete or trailing spaces. When created through script though this isn’t automatically done. So the actual folder names (as listed in Database.views) contained the names with the spaces while the returned array of folder names from the getParentFolder() didn’t.
As trailing spaces are almost impossible to spot in the interface this went undetected.
So while normally (on ordinary folder creation) this Fulltrim() by the getParentFolder() wouldn’t have been a problem, the fact that the folders were being created through script – and users were entering names with extra spaces – meant it caused a discrepancy between the name returned by the function and the name actually used. Or, to put it differently: the inherent ‘human’ factor wasn’t being filtered out.
Lessons learned from this:
- Debugging a mail file with 7000 folders is a pain in the …
- Do a Fulltrim() on any folder name created through code
- And finally… NEVER underestimate the inherent capabilities of users to cause havoc (roughly 1 in 5 folder names contained trailing and or double spaces)
Spent Friday investigating some freakish code problems. This one just blew my mind….
When assigning numbers to a data type what do you expect to happen when you assign a number to big to fit the assigned data type? Right, an overflow error.
Well explain this then….
Ok, yes I know, you can solve it by using “difference# = notesDateTime.TimeDifferenceDouble( notesDateTime )” method which will return a double. I just can’t get my head around the fact that it didn’t return an error when it overflowed on 2,147,483,647 and instead continued up from it’s negative boundary (-2,147,483,648).
Or is this normal behavior for a Long data type?? I just hate it when I can’t logically explain something…
Code I used to test the effect:
Sub Click(Source As Button)
Dim todayD As New NotesDateTime(Today)
Dim AlteredDate As New NotesDateTime(Today)
Set todayD = New NotesDateTime(Today)
todayD.Localtime = todayD.Dateonly + ” 00:00:00″
Set AlteredDate = New NotesDateTime(Today)
AlteredDate.Localtime = AlteredDate.Dateonly + ” 00:00:00″
For x = 24850 To 24860
Set AlteredDate = New NotesDateTime(Today)
If TodayD.Timedifference(AlteredDate)<0 Then
‘EXPECTED OVERFLOW ERROR AT 24857 NOT HAPPENING
Print “TimeDifference between: ” + TodayD.DateOnly + ” and ” +_
AlteredDate.DateOnly + ” = ” + Cstr(TodayD.Timedifference(AlteredDate)) +_
” —- Days: ” + Cstr(x)
Update: I got this answer back through Twitter: “@FemkeGoedhart normal behavior for int/long. See http://en.m.wikipedia.org/wiki/Integer_overflow” Thanks @Thimo! It explains it, although the logic of Lotusscript returning an error on overflow of Integers but not on Longs still eludes me….
Last Friday I was working at a customer where I had to Copy & Paste some person document’s into a secondary address book. Every time I attempted to do it the process would hang and simply wouldn’t stop unless I manually broke it off (CTRL + BREAK). Now I had to paste about 600 records so this was not good news. After some investigation I found the culprit in the “(RenamePastedAccounts)” agent that had an infinite loop in it.
Now this agent is really, really simple. It loops through all the pasted documents and simply checks for a specific value in a field. If found it does something to that field and goes to the next document…..
Right, so do you see the mistake there?
If the value is NOT in the field it will never go to the next document, effectively doing the same check on the same document over and over again.
While Not doc Is Nothing
If ‘value in field’ Then
Set doc = dc.getnextdocument(doc)
It was easy to solve (just move the line that sets the document outside of the If clause) but I just couldn’t help but chuckle. I think it demonstrates a fundamental flaw in development when it comes to testing. We’ve probably all done it. The difficult work you test and have tested but that simple procedure, that so easy to code action…… You know what it needs to do, you know how to do it and you are so confident about what you’re doing that you forget to test it…. thoroughly.
So even at Big Blue, with all it’s checks and testing this can happen it seems. Just glad it’s not my name in that agent, knowing it will be distributed in hundreds of thousands of Domino environments, inevitable found and blogged about on sites around the globe and causing SPR’s to be opened and Technotes to be published…… It’s there for the world to see and there’s nothing you can do but pray everybody upgrades before they ever run into it. And until it is corrected in a new version that honestly simple, stupid mistake will haunt you forever.
Ana……I feel for you.
Coming from someone that only last week managed to literally bring down a (test) server with a similarly simple and obvious coding mistake.
I’ve been busy, really busy the last couple of weeks. Mostly with writing jobs I had to finish. I’m still working on an article and apart from that have been really busy with several reports and Functional Design documents so writing on my blog kind of fell in between.
But in the midst of all that writing I got a good old basic user problem to solve today. A notes 5.0 mail file (yes, I know this customer is really taking his time to upgrade) that had problems with it’s Signature and Archive settings. they seemed to randomly disappear. Fixup didn’t help and to rule out other problems with the profile information documents I decided to simply delete those. Now I’ve done that literally dozens of times with the calendar profile so knowing how to address that profile was no problem. I wasn’t sure about the Archive profile name though, so to be sure I dove into the code to see how it was addressed.
The agent opening the Archive settings called a method:
Mmm…..not a method I am familiar with so I tried the help to see what it did. But I got no luck there, no mention of the method in the help files.
Unusual, Domino methods usually are pretty well documented but at the same time: No problem, the notes community is so well organized that I was sure that I wasn’t the first one looking for this. So I turned to the biggest help file imaginable: The Internet.
Within a couple of seconds I googled several entries noticing what I noticed, that the method wasn’t actually documented although it has been in use since Lotus Notes 5.0. But more importantly, they also provided me with the answer I was looking for: The archive profile is addressed as, yes you guessed it: “Archive Profile”.
Go figure. That simple and predictable answer could have cost me a lot of time hadn’t there have been the Internet. How I ever survived before…..I really don’t know!
ps. Deleting the profiles did the trick as I expected.