From: Jonathan P. <jp...@dc...> - 2005-09-16 13:47:52
|
Hi all, My patch for bridging exceptions between Ruby and Objective C appears to be in the CVS trunk. To go along with this, here's a base-class to be used in place of NSApplication that will pop up an NSAlert when a ruby exception occurs. The alert has 'Continue' and 'Abort' buttons. To use this class, it's necessary to adjust 'rb_main.rb to use RBCApplication in place of NSApplication: if $0 == __FILE__ then rb_main_init OSX::ns_import "RBCApplication" OSX::RBCApplication.sharedApplication OSX.NSApplicationMain(0, nil) end Hope this is of some use. Jonathan // RBCApplication.h #import <Cocoa/Cocoa.h> @interface RBCApplication : NSApplication { } @end // RBCApplication.m @implementation RBCApplication -(void)notifyRubyException:(NSException*)exc { static BOOL handling; if (handling) { NSLog(@"Got an exception %@ while handling another one!",exc); return; } handling = YES; NSMutableString *bs = nil; NSArray *backtrace = [[exc userInfo] objectForKey: @"backtrace"]; if (backtrace) { bs = [NSMutableString string];; [bs appendString: @"Backtrace: \n"]; NSString *resources = [[NSBundle mainBundle] resourcePath]; unsigned int i, count = [backtrace count]; for (i = 0; i < count; i++) { NSString *path = [backtrace objectAtIndex:i]; if ([path hasPrefix: resources]) { path = [path substringFromIndex:[resources length]+1]; } [bs appendFormat: @" %@\n", path]; } } NSString *s = [NSString stringWithFormat: @"An unhandled Ruby exception occurred:\nName: %@\nReason: %@\n%@", [[exc name] substringFromIndex: [@"RBException_" length]], [exc reason], bs ? (NSString*)bs : @""]; NSAlert *alert = [[NSAlert alloc] init]; [alert addButtonWithTitle: @"Continue"]; [alert addButtonWithTitle: @"Abort"]; [alert setMessageText: @"Ruby Exception"]; [alert setInformativeText: s]; if ([alert runModal] == NSAlertSecondButtonReturn) { exit(1); } [alert release]; handling = NO; } -(void)run { while (1) { NS_DURING [super run]; NS_VOIDRETURN; NS_HANDLER if ([[localException name] hasPrefix: @"RBException_"]) { [self notifyRubyException: localException]; } else { [localException raise]; } NS_ENDHANDLER; } } @end |