views:

102

answers:

1

Background

  • I'm using UKCrashReporter in my app.

  • I've installed my own Uncaught Exception Handler.

  • I'm setting up the managedObjectContext of the object activeItemController in applicationDidFinishLaunching (1)

The Problem

If the managedObjectContext method throws an exception, the crash reporter dialog box only flashes up before the app crashes and so the user never gets to report the crash.

I want my app to continue only after the crash has been reported, not whilst the window is showing.

What I've tried

  • If UKCrashReporterCheckForCrash() were an objective C method, I assume I could call performSelectorOnMainThread:waitUntilDone:YES but it's not.

  • I've looked at some other Stack Overflow questions about using Conditional Locks to pause apps, but I can't understand how I'd use it for a C function.

How would I go about doing this in a nice way? Do people have any advice for me? Any responses would be much appreciated.

The Code

// In app delegate

-(void)applicationWillFinishLaunching:(NSNotification *)aNotification {
        UKCrashReporterCheckForCrash();   // A C function which then creates a window if
                                          // it detects a crash has happened.
}

-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [activeItemController setMoContextDisk:[self managedObjectContext]];
    [activeItemController setMoContextMemory:[self managedObjectContextMemory]];
}

Update 1

I've been asked for more details on what I'm trying to do, so here goes.

The bug that triggered this thinking was an exception when merging managedObjectModels. My app got caught in a loop printing "Uncaught exception" to the console every few milliseconds.

And when I installed the uncaught exception handler before this exception happened, I'd get the described behaviour - my app would fire up, display the crash report dialog briefly, then continue to load and crash again.

Summary - I want to be able to handle errors that happen on startup.

(1) I'm not using bindings to do this, as I thought bindings would make testing the class more problematic.

+1  A: 

I think your problem is with thinking of it as "pausing" your app. Think of it more as a different initial UI state. Your attempts to block the run loop will prevent any interactive window from ... well, being interactive. :-)

Your best bet is to show your main UI (and connect data sources, etc) only if the "am I prompting the user to submit a crash report" method says "no, go ahead and start normally". Otherwise, show your window and, when the user sends or declines to send the report, close the window and ask your app controller to continue the normal startup.

I looked at UKCrashReporterCheckForCrash() and it doesn't appear to create a window of any kind. It merely submits the crash. Could you describe what you're doing with more detail?

Joshua Nozzi
That's a great point. I see that having some logic on startup is the way to go. I think I need another nib which only fires up the current nib if there's no crash to report. I'm still not sure quite how I'd go about this, but that gives me a route to explore, so thanks!I'm going to update my question with more details right now.
John Gallagher
In terms of UKCrashReporterCheckForCrash, it does display the crash report window. I think I should get it to post some notifications to indicate that a crash has happened or that the crash report has been delivered, at which point I can continue loading my app.
John Gallagher