Re-running my unit tests on Xcode 9.4, I got stuck on an uncaught exception without any useful debug messages. All I got in the log was:
[...]
Test Case '-[AppTests.AppScriptTests testScriptFiles]' started.
libc++abi.dylib: terminating with uncaught exception of type NSException
and nothing more!
Certainly, I tried re-writing my Swift do-catch-blocks to be able to catch an NSException (Objective-C), but whichever catch line I added, it was never called.
I also tried stepping though the code in the debugger but since the test commands are read from a separate script, and code is spawned on separate threads, this is rather difficult. After trying for a couple of hours yesterday, I gave up.
Today, I remembered a different trick:
Adding an exception breakpoint.
In Xcode,
- open the Breakpoint Navigator (Cmd-8);
- scroll to the bottom and click "+";
- select "Exception Breakpoint…";
- since it was an NSException, I chose Exception: "Objective-C", Break: "On Throw", Action: (none);
With that exception breakpoint active, I could re-run my unit tests. There are quite a few legitimate exception throws in my project. For these, it was just a question of selecting "continue" in debugger until I finally landed on a line that was not meant to crash (the last command shown here):
if let allSelectedIndexPaths = self.tableView.indexPathsForSelectedRows {
for selectedPath in allSelectedIndexPaths {
self.tableView.deselectRow(at: selectedPath, animated: true)
}
self.tableView.reloadRows(at: [ allSelectedIndexPaths ], with: .automatic)
}
So what is wrong with this code?
Answer: A different thread had removed rows from the table view, resulting in me trying to refresh non-existing rows.