realm / realm-swift

Realm is a mobile database: a replacement for Core Data & SQLite
https://realm.io
Apache License 2.0
16.32k stars 2.15k forks source link

Improve error message when throwing due to a reference in a realm class to a non-realm class #5782

Open tachang opened 6 years ago

tachang commented 6 years ago

Goals

I want to initialize realm and not have it crash.

Expected Results

I expect it to not crash the app on startup.

Actual Results

(lldb) bt all
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x0000000114f75d42 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x0000000114fad457 libsystem_pthread.dylib`pthread_kill + 90
    frame #2: 0x0000000114c36107 libsystem_c.dylib`abort + 127
    frame #3: 0x00000001127cd91f libc++abi.dylib`abort_message + 245
    frame #4: 0x00000001127cdabb libc++abi.dylib`default_terminate_handler() + 265
    frame #5: 0x0000000111a1b1be libobjc.A.dylib`_objc_terminate() + 97
    frame #6: 0x00000001127e9159 libc++abi.dylib`std::__terminate(void (*)()) + 8
    frame #7: 0x00000001127e91d3 libc++abi.dylib`std::terminate() + 51
    frame #8: 0x0000000111a1b143 libobjc.A.dylib`objc_terminate + 9
    frame #9: 0x00000001128ec450 libdispatch.dylib`_dispatch_client_callout + 28
    frame #10: 0x00000001128f1af4 libdispatch.dylib`_dispatch_block_invoke_direct + 592
    frame #11: 0x0000000116de1672 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    frame #12: 0x0000000116de1328 FrontBoardServices`-[FBSSerialQueue _performNext] + 464
    frame #13: 0x0000000116de1897 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
    frame #14: 0x000000010d8712b1 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #15: 0x000000010d910d31 CoreFoundation`__CFRunLoopDoSource0 + 81
    frame #16: 0x000000010d855c19 CoreFoundation`__CFRunLoopDoSources0 + 185
    frame #17: 0x000000010d8551ff CoreFoundation`__CFRunLoopRun + 1279
    frame #18: 0x000000010d854a89 CoreFoundation`CFRunLoopRunSpecific + 409
    frame #19: 0x00000001176d49c6 GraphicsServices`GSEventRunModal + 62
    frame #20: 0x0000000112a52d30 UIKit`UIApplicationMain + 159
  * frame #21: 0x000000010c8d733f Literator`main(argc=1, argv=0x00007fff5339d168) at main.m:14
    frame #22: 0x0000000112968d81 libdyld.dylib`start + 1
    frame #23: 0x0000000112968d81 libdyld.dylib`start + 1
  thread #2
    frame #0: 0x0000000114f7644e libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x0000000114faa48e libsystem_pthread.dylib`_pthread_wqthread + 1023
    frame #2: 0x0000000114faa07d libsystem_pthread.dylib`start_wqthread + 13
  thread #3
    frame #0: 0x0000000114faa070 libsystem_pthread.dylib`start_wqthread
  thread #4, queue = 'com.twitter.crashlytics.ios.binary-images'
    frame #0: 0x000000010d7d94a5 CoreFoundation`__CFBasicHashRehash + 1333
    frame #1: 0x000000010d7ded0b CoreFoundation`__CFBasicHashAddValue + 91
    frame #2: 0x000000010d7dfc55 CoreFoundation`CFDictionarySetValue + 277
    frame #3: 0x000000010d7f0d97 CoreFoundation`_CFBundleCreate + 1367
    frame #4: 0x00000001111c7cbb Foundation`-[NSBundle _cfBundle] + 72
    frame #5: 0x00000001111c7c3c Foundation`-[NSBundle infoDictionary] + 19
    frame #6: 0x00000001111c84af Foundation`-[NSBundle bundleIdentifier] + 22
    frame #7: 0x000000010c988846 Literator`__CLSBinaryImageChanged_block_invoke + 378
    frame #8: 0x00000001128eb3f7 libdispatch.dylib`_dispatch_call_block_and_release + 12
    frame #9: 0x00000001128ec43c libdispatch.dylib`_dispatch_client_callout + 8
    frame #10: 0x00000001128f495b libdispatch.dylib`_dispatch_queue_serial_drain + 1162
    frame #11: 0x00000001128f52df libdispatch.dylib`_dispatch_queue_invoke + 336
    frame #12: 0x00000001128f107d libdispatch.dylib`_dispatch_queue_override_invoke + 733
    frame #13: 0x00000001128f81f9 libdispatch.dylib`_dispatch_root_queue_drain + 772
    frame #14: 0x00000001128f7e97 libdispatch.dylib`_dispatch_worker_thread3 + 132
    frame #15: 0x0000000114faa5a2 libsystem_pthread.dylib`_pthread_wqthread + 1299
    frame #16: 0x0000000114faa07d libsystem_pthread.dylib`start_wqthread + 13
  thread #5, name = 'com.apple.uikit.eventfetch-thread'
    frame #0: 0x0000000114f6e34a libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x0000000114f6d797 libsystem_kernel.dylib`mach_msg + 55
    frame #2: 0x000000010d855e85 CoreFoundation`__CFRunLoopServiceMachPort + 213
    frame #3: 0x000000010d8553c2 CoreFoundation`__CFRunLoopRun + 1730
    frame #4: 0x000000010d854a89 CoreFoundation`CFRunLoopRunSpecific + 409
    frame #5: 0x00000001111dfe5e Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 274
    frame #6: 0x000000011125d9b7 Foundation`-[NSRunLoop(NSRunLoop) runUntilDate:] + 87
    frame #7: 0x00000001136977e9 UIKit`-[UIEventFetcher threadMain] + 118
    frame #8: 0x00000001111ed8ac Foundation`__NSThread__start__ + 1197
    frame #9: 0x0000000114faa93b libsystem_pthread.dylib`_pthread_body + 180
    frame #10: 0x0000000114faa887 libsystem_pthread.dylib`_pthread_start + 286
    frame #11: 0x0000000114faa08d libsystem_pthread.dylib`thread_start + 13
  thread #6
    frame #0: 0x0000000114f7644e libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x0000000114faa621 libsystem_pthread.dylib`_pthread_wqthread + 1426
    frame #2: 0x0000000114faa07d libsystem_pthread.dylib`start_wqthread + 13
  thread #8
    frame #0: 0x0000000114f7644e libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x0000000114faa621 libsystem_pthread.dylib`_pthread_wqthread + 1426
    frame #2: 0x0000000114faa07d libsystem_pthread.dylib`start_wqthread + 13
  thread #9
    frame #0: 0x0000000114faa070 libsystem_pthread.dylib`start_wqthread
  thread #10
    frame #0: 0x0000000114f7644e libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x0000000114faa621 libsystem_pthread.dylib`_pthread_wqthread + 1426
    frame #2: 0x0000000114faa07d libsystem_pthread.dylib`start_wqthread + 13
  thread #11, name = 'com.apple.NSURLConnectionLoader'
    frame #0: 0x0000000114f6e34a libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x0000000114f6d797 libsystem_kernel.dylib`mach_msg + 55
    frame #2: 0x000000010d855e85 CoreFoundation`__CFRunLoopServiceMachPort + 213
    frame #3: 0x000000010d8553c2 CoreFoundation`__CFRunLoopRun + 1730
    frame #4: 0x000000010d854a89 CoreFoundation`CFRunLoopRunSpecific + 409
    frame #5: 0x000000010fe8e8c1 CFNetwork`+[NSURLConnection(Loader) _resourceLoadLoop:] + 406
    frame #6: 0x00000001111ed8ac Foundation`__NSThread__start__ + 1197
    frame #7: 0x0000000114faa93b libsystem_pthread.dylib`_pthread_body + 180
    frame #8: 0x0000000114faa887 libsystem_pthread.dylib`_pthread_start + 286
    frame #9: 0x0000000114faa08d libsystem_pthread.dylib`thread_start + 13
(lldb) 

Steps to Reproduce

Inside AppDelegate.m put

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
    config.inMemoryIdentifier = @"MyInMemoryRealm";
    DDLogDebug(@"Before Realm configuration");
    RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
    DDLogDebug(@"After Realm configuration");

Code Sample


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Initialize logging mechanism
    [DDLog addLogger:[DDTTYLogger sharedInstance]];

    // Initialize Mixpanel library with API token
    [Mixpanel sharedInstanceWithToken:MIXPANEL_PROJECT_TOKEN ];
    [[Mixpanel sharedInstance] setEnableLogging:NO];

    // Initialize Crashlytics
    [Fabric with:@[[Crashlytics class]]];

    // initialize the session, setup a deep link handler
    [[Branch getInstance] initSessionWithLaunchOptions:launchOptions
                            andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) {

        DDLogDebug(@"Deep link received with params: %@ ", params);

        if ([params[@"~channel"] isEqualToString:@"In-App Referral"]) {
            DDLogDebug(@"In-App Referral received with code: %@", params[@"code"]);

            // Persist referral metadata locally so that it can be accessed later
            [[NSUserDefaults standardUserDefaults] setObject:params[@"code"] forKey:@"referral_code_used"];

        }
    }];

    // Style the navigation and status bar color and back button
    [self styleCommonNavigationElements];

    RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
    config.inMemoryIdentifier = @"MyInMemoryRealm";
    DDLogDebug(@"Before Realm configuration");
    RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
    DDLogDebug(@"After Realm configuration");

}

Version of Realm and Tooling

ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G29

/Applications/Xcode.app/Contents/Developer
Xcode 9.0
Build version 9A235

/usr/local/bin/pod
1.4.0
Realm (3.5.0)

/bin/bash
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)

(not in use here)

/usr/local/bin/git
git version 2.6.3
tachang commented 6 years ago

After loading up Realm using Pod so I had the source it turned out it was this code:

        try {
            // Make sure we've discovered all classes
            {
                unsigned int numClasses;
                using malloc_ptr = std::unique_ptr<__unsafe_unretained Class[], decltype(&free)>;
                malloc_ptr classes(objc_copyClassList(&numClasses), &free);
                RLMRegisterClassLocalNames(classes.get(), numClasses);
            }

            [s_localNameToClass enumerateKeysAndObjectsUsingBlock:^(NSString *, Class cls, BOOL *) {
                RLMRegisterClass(cls);
            }];
        }
        catch (...) {
            s_sharedSchemaState = SharedSchemaState::Uninitialized;
            throw;
        }

Is there anyway to make the throw give a better error message? It turned out that it was erroring out in RLMRegisterClass. The class I had used a point type that I didn't have as a Realm object yet so it just completely broke.

bmunkholm commented 6 years ago

@tachang So to be clear, you have fixed your problem, but suggest to improve the error handling? Does the new title reflect it properly?

bmunkholm commented 6 years ago

Seems like an easy starter task