Looks like you have an empty session list. Have you ever used Safari? Quick workaround might be to pop open Safari once (and browse a little) and then try again.
Why on earth would anyone downvote this comment? The lack of a Safari user profile is the most obvious potential issue here, based on the backtrace.
Re:OS X Auditor
by w0rd-driven on Monday September 15, 2014 @01:25PM
(#8320080)
That's the precise problem I had. Opening Safari got me one step closer and then another failure. I wanted to run all options but got tired of all these errors so I commented out ParseSafari, ParseFirefox, and ParseChrome calls inside the ParseBrowsers function. I could've left Firefox or Chrome but not wanting to shut Chrome down or not using Firefox much, I didn't want to go through this again for each browser.
And that, folks, is why we don't do chained expressions. Variables increase readability and also offer one the opportunity to check a condition that should be true.
This, KeyError, NoneType exceptions and its Java friend NullPointerException drive me batty. They are so simple to defend against, if the author just took the time.
Chaining itself isn't really the problem here IMO. Creating a variable for each level of the nested data structure and manually checking for the validity of each subsequent one would really, really not produce more readable code. It would turn a "get this value out of a data structure" expression into about 15 lines of code that each need to be individually read and understood. The problem is that Cocoa doesn't provide a great way to say "Access this stuff in this data structure unless it isn't there."
An option type is really the best way to kill this breed of problem, and thankfully Apple is including one in Swift, though it's still somewhat green.
That's a Obj-C problem, because it's being fixed with what Swift does with it's '?' on variables. :)
Not exactly. This program would have the same problem in Swift, because rather than returning optionals, Swift arrays have the same explode-on-invalid-accesses behavior as NSArray.
Maybe monads make this kind of chaining safe.
The accessor variant of the existential operator in CoffeeScript (which Swift apparently has taken influence from) handles this nicely.
I love Optionals for this.
I can't even get pyobjc running on 10.9..
~/Library/Safari/LastSession.plist Traceback (most recent call last): File "osxauditor.py", line 1702, in <module> Main() File "osxauditor.py", line 1663, in Main ParseBrowsers() File "osxauditor.py", line 808, in ParseBrowsers ParseSafari() File "osxauditor.py", line 745, in ParseSafari ParseSafariProfile(User, UserSafariProfilePath) File "osxauditor.py", line 717, in ParseSafariProfile LastSession = LastSessionPlist["SessionWindows"][0]["TabStates"][0] File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC/objc/_convenience.py", line 451, in __getitem__objectAtIndex_ return container_unwrap(self.objectAtIndex_(idx), RuntimeError) IndexError: NSRangeException - -[__NSCFArray objectAtIndex:]: index (0) beyond bounds (0)