Tuesday, February 18, 2014

"Unresponsive script" with Developer Console

The Developer Console for Salesforce.com is entirely Javascript based, so it's subject to all Javascript can offer in your browser, good and bad.  One annoying thing is that Javascript can be slow for certain things, for instance, enumerating a large list.  This is especially acute for me when listing the test classes available.  We probably have 250+ test classes in our main org (all namespaces included), and that always seems too much for the console's Javascript to handle no matter what computer I use (currently on an i7 with 8gb memory), which results in an "Unresponsive script" error in Firefox so I have to click "Continue" for it to finish loading.  So I deal with it this way:

  1. Type in about:config in the address bar and press Enter.  This gives you the master list of all settings you can manually adjust in Firefox. 
  2. After confirming that you'd be careful with the settings, search for this setting string: dom.max_script_run_time.  This controls when the browser will complain and give you a chance to terminate the script (in number of seconds). Change the value to a bigger number - default is 10 and I use 20.
I do this for all Firefox profiles I use often with the Developer Console.  Chrome seems to be more forgiving/patient with the script compared to Firefox, so there is no error message - you just have to wait until the screen is unfrozen.

UPDATE: I'm happy to report that this trick seems to be no longer necessary with Summer '14.  The test class list in the console seems to be much more speedy and non-blocking to start - kudos to the developers!

Thursday, February 13, 2014

Salesforce domain name management: you can only have three wishes

You can really have a bunch of stuff under the Domains section, and sometimes wonder how they ended up there.  Some you probably know well, because you actually asked your domain/DNS administrator to create the redirect/alias once you assign the names to your Sites.  But there are some in there you can neither edit nor delete from the list.  They are the genie wishes with your Salesforce domains.  Let's look at an example and see what they really are.


  1. That's My Domain name.  When you enable that feature, you'll need to pick the name, and it will appear in all the URLs of your Salesforce org pages.
  2. That comes from Sites.  This subdomain name is the real URL start of all Sites pages.  You may have your own domain URLs over those, but eventually your DNS servers need to know where to redirect the visitors to the real URLs.
  3. That's for your Communities.  Once picked when you enable the feature, that becomes the real URL start for all Community sites, which are essentially special Sites.
These 3 are truly genie wishes in the sense that once you asked Salesforce to grant them, and were indeed granted (at the time of feature activation), you can neither change them nor take back.  They're stuck with you for eternity (of the org).  So choose wisely!  You are certainly constrained by your organization's name or traditional marketing tags, but if you do have some options, try to pick nice, short, and generic names.  It's easy to understand why being nice and short matters, but being generic is often overlooked.  When you start to use Sites or Communities it's often a specific need, but the name will be applied to all subsequent uses, which may have nothing in common with the initial project.  So being generic is also important.

Friday, February 7, 2014

Converting DateTime to Date in Apex: Undocumented Pitfall

All roads lead to Rome... almost.  There's more than one way to do the conversion in Apex, and they yield subtle but meaningful differences.  Consider these two statements:

system.debug(Date.Valueof(DateTime.valueof('2014-02-06 21:11:11')));

system.debug(DateTime.valueof('2014-02-06 21:11:11').date());

Both on the surface do an explicit type cast from DateTime to Date, but the results are different.  An important note: I ran them as an Eastern Time Zone user.  Here are the results:

10:12:51.045 (45992000)|USER_DEBUG|[8]|DEBUG|2014-02-07 02:11:11
10:12:51.046 (46064000)|USER_DEBUG|[9]|DEBUG|2014-02-06 00:00:00

Semantically the second statement has the right answer: as a user in EST, I expect to get the date in my time zone, which should be Feb 6th.  The first one seems to supply a GMT date.  Also note it still has the time part.  Weird.

The catch here is, Date.valueOf(DateTime) doesn't exist in the official documentation.  Date.valueOf(Object) does exist, but that's meant to be used only with history tracking values.  Since it's not officially supported, I guess you can't blame Salesforce officially for the unexpected result.

I didn't use the undocumented method on purpose - I just did it assuming it's there.  Apex, after all, is only almost strongly typed, because we don't have well-documented rules for type casting.  I crossed the boundary, and I was on my own.  Well, it wasn't that bad - it just cost me some extra time to figure out why the hell the test failed at night, when it ran flawlessly during the day.


Wednesday, February 5, 2014

Symform on Linux

So the hard drive on one of my Symform devices died.  It was a laptop running Windows Vista, which is one of those undying-one-time-hack situations.  No point to rebuild it so I swapped in a hard drive, which already had Ubuntu 10.04 on it (don't remember when I did that).  After some minor reconfig I got it work properly and installed the Symform client.  The Web interface was pretty convenient - much better than the desktop app on Windows.  However even with port forwarding configured I still don't see a heartbeat from https://control.symform.com.  Here's where the UI starts to fall short: I really don't have a way to further troubleshoot it.  I had to drop into command and start going through the community forum.  Not really complaining about this when working on Linux, but if you have a GUI, why not put some quick indicators and info for troubleshooting?

Anyhow I eventually noticed the contribution service isn't staying on (/opt/symform/SymformNode.sh status).  A check through the exception stack in the log (/var/log/symformcontrib.log) made it clear that the process couldn't really access the contribution folder.  I had no problem selecting it from the UI, but the folder is on an USB drive that was used by the old Windows machine.  As auto-mounted the NTFS volume had no permission for the symform UID, which runs the needed process.  I remounted the volume with umask=0 and it started to work.