The first thing you’ll need to do is enable the debug menu in Safari. To do this, go to Safari->PreferencesAdvanced in the main menu, and choose the tab. In there, enable Show Develop menu in menu bar:
Click on the arrow icon to the right of the message, and you’ll be taken to the exact source line in the script where the problem occurred. This is a very straightforward interface to track down a lot of common problems, much better integrated than Microsoft’s Script Debugger. In my case it wasn’t enough though, the error happened in the middle of some very complex code, and it seemed like the result of a logic error that happened much earlier. That meant I needed a debugger that I could use to step through the code.
Happily, I discovered Drosera. This is a fully-featured debugger that’s part of the WebKit project. In recent versions of the open source project it’s been integrated into the Web Inspector, but for shipping versions of Safari 3 you can still download it as a separate application.
Once you’ve downloaded it, you need to run the following line on the terminal and restart Safari:
defaults write com.apple.Safari WebKitScriptDebuggerEnabled -bool true
Then, run the Drosera application, and select Safari from the attachment window:
Now just load the page you want to debug. Whenever there’s an exception or an error the debugger will pause Safari and let you inspect the script and all its variables. To see the value of any variable, open up the Console section of the debugger and type the name into the bottom pane. If you want a breakpoint, just select the script file in the debugger’s side pane and click on the number just to the left of the line you want to stop at.
For the OpenCalais problem, it turned out to be an exception that was thrown and caught early in the script was causing the later problem. Drosera paused on the exception automatically the first time I loaded the page, and after a little bit of inspection I was able to figure out that it was using a function that wasn’t supported in Safari. I’m glad I took the time to download the debugger, I could have spent hours trying to figure that out from inspecting the code otherwise.