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

Crash in @ObservedResults getter #8180

Closed drmarkpowell closed 1 year ago

drmarkpowell commented 1 year ago

How frequently does the bug occur?

Sometimes

Description

Users running our Realm app run .isEmpty() on @ObservedResults and this throws an internal RLMException that crashes the app.

Stacktrace & log output

Fatal Exception: RLMException
0  CoreFoundation                 0x9e88 __exceptionPreprocess
1  libobjc.A.dylib                0x178d8 objc_exception_throw
2  MyApp                      0x412b64 RLMThrowCollectionException(NSString*) + 92 (RLMResults.mm:92)
3  MyApp                      0x414f30 -[RLMResults resolveInRealm:] + 60 (RLMResults_Private.hpp:60)
4  MyApp                      0x414f90 -[RLMResults freeze] + 525 (RLMResults.mm:525)
5  MyApp                      0x472fe4 RealmCollectionImpl.freeze() + 140 (RealmCollectionImpl.swift:140)
6  MyApp                      0x4c953c ObservedResults.wrappedValue.getter (<compiler-generated>)
7  MyApp                      0x90bc0 SearchView.noSearchResults() (<compiler-generated>)
8  MyApp                      0x9031c closure #1 in closure #1 in closure #1 in closure #1 in closure #1 in closure #1 in SearchView.body.getter + 44 (SearchView.swift:44)
9  SwiftUI                        0xe01034 OUTLINED_FUNCTION_47
10 MyApp                      0x99db8 partial apply for closure #1 in closure #1 in closure #1 in closure #1 in closure #1 in SearchView.body.getter (<compiler-generated>)
11 SwiftUI                        0x1d4c00 OUTLINED_FUNCTION_217
12 MyApp                      0x8ff34 closure #1 in closure #1 in closure #1 in closure #1 in SearchView.body.getter + 62 (SearchView.swift:62)
13 SwiftUI                        0x24142c OUTLINED_FUNCTION_897
14 MyApp                      0x99c48 partial apply for closure #1 in closure #1 in closure #1 in SearchView.body.getter (<compiler-generated>)
15 SwiftUI                        0x1f3ed0 OUTLINED_FUNCTION_169
16 SwiftUI                        0x202a94 OUTLINED_FUNCTION_707
17 SwiftUI                        0xe6db4 _callVisitToolbarContentType1
18 SwiftUI                        0xfe798 OUTLINED_FUNCTION_279
19 SwiftUI                        0x11db44c OUTLINED_FUNCTION_23
20 SwiftUI                        0x6555c __swift_allocate_boxed_opaque_existential_0
21 AttributeGraph                 0x46f4 AG::Graph::UpdateStack::update()
22 AttributeGraph                 0x3f44 AG::Graph::update_attribute(AG::data::ptr<AG::Node>, unsigned int)
23 AttributeGraph                 0x2c00 AG::Subgraph::update(unsigned int)
24 SwiftUI                        0xcfd8 OUTLINED_FUNCTION_15
25 SwiftUI                        0x1c3f8 OUTLINED_FUNCTION_157
26 SwiftUI                        0xc0bf0 OUTLINED_FUNCTION_450
27 SwiftUI                        0x2f8a4 OUTLINED_FUNCTION_173
28 SwiftUI                        0x33728 __swift_memcpy80_8
29 UIKitCore                      0x5020 -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
30 QuartzCore                     0x99ec CA::Layer::layout_if_needed(CA::Transaction*)
31 QuartzCore                     0x1d0a0 CA::Layer::layout_and_display_if_needed(CA::Transaction*)
32 QuartzCore                     0x2e5b0 CA::Context::commit_transaction(CA::Transaction*, double, double*)
33 QuartzCore                     0x635ec CA::Transaction::commit()
34 QuartzCore                     0x4c8cc CA::Transaction::flush_as_runloop_observer(bool)
35 UIKitCore                      0x504b44 _UIApplicationFlushCATransaction
36 UIKitCore                      0x652740 _UIUpdateSequenceRun
37 UIKitCore                      0xc99fd0 schedulerStepScheduledMainSection
38 UIKitCore                      0xc9919c runloopSourceCallback
39 CoreFoundation                 0xd5f54 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
40 CoreFoundation                 0xe232c __CFRunLoopDoSource0
41 CoreFoundation                 0x66270 __CFRunLoopDoSources0
42 CoreFoundation                 0x7bba8 __CFRunLoopRun
43 CoreFoundation                 0x80ed4 CFRunLoopRunSpecific
44 GraphicsServices               0x1368 GSEventRunModal
45 UIKitCore                      0x3a23d0 -[UIApplication _run]
46 UIKitCore                      0x3a2034 UIApplicationMain
47 SwiftUI                        0x1d1014 OUTLINED_FUNCTION_895
48 SwiftUI                        0x13216c block_copy_helper.1
49 SwiftUI                        0x11b4bc OUTLINED_FUNCTION_901
50 MyApp                      0x8e54 main (<compiler-generated>)
51 ???                            0x1ab604960 (Missing)

Crashed: com.google.firebase.crashlytics.ios.exception
0  MyApp                      0x157740 FIRCLSProcessRecordAllThreads + 393 (FIRCLSProcess.c:393)
1  MyApp                      0x157b20 FIRCLSProcessRecordAllThreads + 424 (FIRCLSProcess.c:424)
2  MyApp                      0x164fcc FIRCLSHandler + 34 (FIRCLSHandler.m:34)
3  MyApp                      0x164e20 __FIRCLSExceptionRecord_block_invoke + 232 (FIRCLSException.mm:232)
4  libdispatch.dylib              0x3fdc _dispatch_client_callout + 20
5  libdispatch.dylib              0x13574 _dispatch_lane_barrier_sync_invoke_and_complete + 56
6  MyApp                      0x163e2c FIRCLSExceptionRecord + 234 (FIRCLSException.mm:234)
7  MyApp                      0x164940 FIRCLSExceptionRecordNSException + 126 (FIRCLSException.mm:126)
8  MyApp                      0x163a84 FIRCLSTerminateHandler() + 398 (FIRCLSException.mm:398)
9  libc++abi.dylib                0x10f28 std::__terminate(void (*)()) + 20
10 libc++abi.dylib                0x13ecc __cxa_rethrow + 148
11 libobjc.A.dylib                0x196b4 objc_exception_rethrow + 44
12 CoreFoundation                 0x80f98 CFRunLoopRunSpecific + 808
13 GraphicsServices               0x1368 GSEventRunModal + 164
14 UIKitCore                      0x3a23d0 -[UIApplication _run] + 888
15 UIKitCore                      0x3a2034 UIApplicationMain + 340
16 SwiftUI                        0x1d1014 OUTLINED_FUNCTION_895 + 2420
17 SwiftUI                        0x13216c block_copy_helper.1 + 388
18 SwiftUI                        0x11b4bc OUTLINED_FUNCTION_901 + 2868
19 MyApp                      0x8e54 main + 4364881492 (<compiler-generated>:4364881492)
20 ???                            0x1ab604960 (Missing)

Thread
0  libsystem_kernel.dylib         0x1050 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0xe44 _pthread_wqthread + 364
2  libsystem_pthread.dylib        0xb98 start_wqthread + 8

com.apple.uikit.eventfetch-thread
0  libsystem_kernel.dylib         0xb48 mach_msg2_trap + 8
1  libsystem_kernel.dylib         0x13008 mach_msg2_internal + 80
2  libsystem_kernel.dylib         0x13248 mach_msg_overwrite + 388
3  libsystem_kernel.dylib         0x108c mach_msg + 24
4  CoreFoundation                 0x7aaf0 __CFRunLoopServiceMachPort + 160
5  CoreFoundation                 0x7bd34 __CFRunLoopRun + 1232
6  CoreFoundation                 0x80ed4 CFRunLoopRunSpecific + 612
7  Foundation                     0x42334 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
8  Foundation                     0x4221c -[NSRunLoop(NSRunLoop) runUntilDate:] + 64
9  UIKitCore                      0x4d733c -[UIEventFetcher threadMain] + 436
10 Foundation                     0x5b808 __NSThread__start__ + 716
11 libsystem_pthread.dylib        0x16cc _pthread_start + 148
12 libsystem_pthread.dylib        0xba4 thread_start + 8

Thread
0  libsystem_kernel.dylib         0x1050 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0xe44 _pthread_wqthread + 364
2  libsystem_pthread.dylib        0xb98 start_wqthread + 8

com.google.firebase.crashlytics.MachExceptionServer
0  libsystem_kernel.dylib         0xb48 mach_msg2_trap + 8
1  libsystem_kernel.dylib         0x13008 mach_msg2_internal + 80
2  libsystem_kernel.dylib         0x13248 mach_msg_overwrite + 388
3  libsystem_kernel.dylib         0x108c mach_msg + 24
4  MyApp                      0x165584 FIRCLSMachExceptionServer + 192 (FIRCLSMachException.c:192)
5  libsystem_pthread.dylib        0x16cc _pthread_start + 148
6  libsystem_pthread.dylib        0xba4 thread_start + 8

com.apple.NSURLConnectionLoader
0  libsystem_kernel.dylib         0xb48 mach_msg2_trap + 8
1  libsystem_kernel.dylib         0x13008 mach_msg2_internal + 80
2  libsystem_kernel.dylib         0x13248 mach_msg_overwrite + 388
3  libsystem_kernel.dylib         0x108c mach_msg + 24
4  CoreFoundation                 0x7aaf0 __CFRunLoopServiceMachPort + 160
5  CoreFoundation                 0x7bd34 __CFRunLoopRun + 1232
6  CoreFoundation                 0x80ed4 CFRunLoopRunSpecific + 612
7  CFNetwork                      0x2565a8 _CFURLStorageSessionDisableCache + 61088
8  Foundation                     0x5b808 __NSThread__start__ + 716
9  libsystem_pthread.dylib        0x16cc _pthread_start + 148
10 libsystem_pthread.dylib        0xba4 thread_start + 8

Thread
0  libsystem_kernel.dylib         0x1050 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0xe44 _pthread_wqthread + 364
2  libsystem_pthread.dylib        0xb98 start_wqthread + 8

Thread
0  libsystem_kernel.dylib         0x1050 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0xe44 _pthread_wqthread + 364
2  libsystem_pthread.dylib        0xb98 start_wqthread + 8

Thread
0  libsystem_kernel.dylib         0x2480 kevent + 8
1  MyApp                      0x6f3590 realm::sync::network::Service::IoReactor::wait_and_activate(std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >, std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >) + 801 (network.cpp:801)
2  MyApp                      0x6f3bc4 realm::sync::network::Service::IoReactor::wait_and_advance(std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >, std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >, bool&, realm::sync::network::Service::OperQueue<realm::sync::network::Service::AsyncOper>&) + 909 (network.cpp:909)
3  MyApp                      0x6f5a8c realm::sync::network::Service::Impl::run_impl(bool) + 1639 (network.cpp:1639)
4  MyApp                      0x6e8d40 realm::sync::websocket::DefaultSocketProvider::event_loop() + 584 (default_socket.cpp:584)
5  MyApp                      0x6ea4f0 void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (realm::sync::websocket::DefaultSocketProvider::*)(), realm::sync::websocket::DefaultSocketProvider*> >(void*) + 191 (tuple:191)
6  libsystem_pthread.dylib        0x16cc _pthread_start + 148
7  libsystem_pthread.dylib        0xba4 thread_start + 8

Realm notification listener
0  libsystem_kernel.dylib         0x2480 kevent + 8
1  MyApp                      0x5a02ec realm::_impl::ExternalCommitHelper::listen() + 220 (external_commit_helper.cpp:220)
2  MyApp                      0x5a04cc void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, realm::_impl::ExternalCommitHelper::ExternalCommitHelper(realm::_impl::RealmCoordinator&, realm::RealmConfig const&)::$_0> >(void*) + 191 (tuple:191)
3  libsystem_pthread.dylib        0x16cc _pthread_start + 148
4  libsystem_pthread.dylib        0xba4 thread_start + 8

Can you reproduce the bug?

Sometimes

Reproduction Steps

These stack traces are collected from users running our app in production and we have not yet reproduced it manually, yet.

Version

10.37.0

What Atlas Services are you using?

Atlas Device Sync

Are you using encryption?

No

Platform OS and version(s)

iOS 13.2.1

Build environment

Xcode version: 14.2 Dependency manager and version: SPM

dianaafanador3 commented 1 year ago

Hi @drmarkpowell can you please attach the info of the exception you're getting. Also can you please share the code on your SearchView, and how you inject/create the Realm used by the @ObservedResults. From the look of it, seems like you are accessing the results from a different thread that the one the realm was created.

drmarkpowell commented 1 year ago

The issue occurs randomly for users in production and I haven't duplicated it locally yet...so I can't share any additional details about the RLMException since I can't get them. The @ObservedResults getters doesn't throw any Exceptions, so I can't catch them and dump them (AFAIK).

Providing a bunch more code, redacted as little as possible to protect private details. I also have an open MongoDB support ticket on this where I am providing additional details if that is helpful at all.

struct MyApp: SwiftUI.App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @StateObject private var login = LoginViewModel.shared

    var body: some Scene {
        return WindowGroup {
            VStack {
                if login.cognitoIdToken.isEmpty {
                    LoginView(login: login)
                        .frame(height: 0)
                } else if let realmConfig = RealmController.realmConfiguration("abc") {
                    OpenSyncedRealmView(idToken: login.cognitoIdToken)
                        .environment(\.realmConfiguration, realmConfig)
                } else {
                    OpenSyncedRealmView(idToken: login.cognitoIdToken)
                }
            }
        }
    }

struct OpenSyncedRealmView: View {
    @StateObject var progressViewModel = SyncProgressViewModel()
    @AutoOpen(
        appId: RealmAppId.shared.id,
        partitionValue: "abc",
        configuration: RealmController.realmConfiguration("abc"),
        timeout: 5000
    ) var abcRealm

    var idToken: String

    var body: some View {
        switch abcRealm {
        case .connecting:
            ProgressView("Connecting...")
        case .waitingForUser:
            loginView()
        case .open(let realm):
            if let realmConfig = RealmController.realmConfiguration("abc") {
                tabView(realm, realmConfig)
                    .environmentObject(AppController.shared.app)
            } else {
                tabView(realm)
                    .environmentObject(AppController.shared.app)
            }
        case .progress(let progress):
            PleaseWaitLoadingDataView(progress: progressViewModel)
                .task { @MainActor in
                    progressViewModel.progress = progress
                }
        case .error(let error):
            Text(error.localizedDescription)
        }
    }

    func tabView(_ realm: Realm, _ realmConfig: Realm.Configuration) -> some View {
        RealmController.shared.realm = realm
        return ABCTabView()
            .environment(\.realm, realm)
            .environment(\.realmConfiguration, realmConfig)
    }

    func tabView(_ realm: Realm) -> some View {
        RealmController.shared.realm = realm
        return ABCTabView()
            .environment(\.realm, realm)
    }

    func loginView() -> some View {
        AppController.shared.app.login(credentials: .jwt(token: idToken)) { result in
            if case let .failure(error) = result {
                print("Login failed: \(error.localizedDescription)")
            } else {
                print("Login success: \(result)")
            }
        }

        return ProgressView("Logging in...")
    }
}

class RealmController: ObservableObject {
    static var shared =  RealmController()
    static let resetModeHandler = ClientResetMode.recoverOrDiscardUnsyncedChanges(beforeReset: { _ in
        os_log(.error, "before client reset")
    }, afterReset: { (_, _) in
        os_log(.error, "after client reset")
    })

    @Published var lastDownload: Date? = UserDefaults.standard.value(forKey: lastDownloadKey) as? Date ?? nil
    @Published var online: Bool = false

    var realm: Realm? {
        didSet {
            do {
                xyzRealm = try RealmController.configureRealm(.xyz)
            } catch let error {
                print("Error configuring xyz realm: \(error.localizedDescription)")
            }
            do {
                defRealm = try RealmController.configureRealm(.def)
            } catch let error {
                print("Error configuring def realm: \(error.localizedDescription)")
            }
            do {
                userRealm = try RealmController.configureRealm(.user)
            } catch let error {
                print("Error configuring user realm: \(error.localizedDescription)")
            }
            do {
                usRealm = try RealmController.configureRealm(.us)
            } catch let error {
                print("Error configuring us realm: \(error.localizedDescription)")
            }

            // clean up any existing network reachability or download monitors
            stopReachabilty()
            stopRealmNotification()

            // set up the network reachability and download monitors
            setupReachability()
            setupRealmNotification()
        }
    }
    var userRealm: Realm?
    var xyzRealm: Realm?
    var vwRealm: Realm?
    var defRealm: Realm?
    var downloadProgressToken: SyncSession.ProgressNotificationToken?
    let reachability = try? Reachability(hostname: "www.amazon.com")

    private init() {
    }

    deinit {
        stopReachabilty()
        stopRealmNotification()
     }

    static func realmConfiguration(_ partitionId: String) -> Realm.Configuration? {
        if let user = AppController.shared.app.currentUser {
            var realmConfiguration = user.configuration(
                partitionValue: partitionId,
                clientResetMode: resetModeHandler
            )
            realmConfiguration.schemaVersion = AppController.SCHEMA_VERSION
            return realmConfiguration
        }
        return nil
    }

    static func configureRealm(_ realmType: RealmType) throws -> Realm? {
        guard let user = AppController.shared.app.currentUser else {
            return nil
        }
        switch realmType {
        case .abc:
            return try createRealm("abc", user)
        case .def:
            return isdef() ? try createRealm("def", user) : nil
        case .xyz:
            return isxyz() ? try createRealm("xyz", user) : nil
        case .vw:
            return isvw() ? try createRealm("vw", user) : nil
        case .user:
            return !username().isEmpty ? try createRealm(username(), user) : nil
        }
    }

    static func createRealm(_ partition: String, _ user: RealmSwift.User) throws -> Realm {
        return try Realm(configuration: user.configuration(
            partitionValue: partition,
            clientResetMode: resetModeHandler
        ))
    }

    func resumeAllSessions() {
        realm?.syncSession?.resume()
        userRealm?.syncSession?.resume()
        xyzRealm?.syncSession?.resume()
        defRealm?.syncSession?.resume()
        vwRealm?.syncSession?.resume()
    }

    func invalidateRealms() {
        realm?.invalidate()
        userRealm?.invalidate()
        xyzRealm?.invalidate()
        defRealm?.invalidate()
        vwRealm?.invalidate()
    }
}

struct SearchView: View {

    @ObservedResults(Favorite.self, configuration: userConfig()) var favorites
    @ObservedResults(RecentSearchResult.self, configuration: userConfig(), sortDescriptor: RecentSearchResult.sortDescriptor()) var recents
    @ObservedResults(Person.self, configuration: abcConfig(), filter: Person.defaultPredicate, sortDescriptor: Person.sortDescriptor()) var peopleResults
    @ObservedResults(Cafeteria.self, configuration: abcConfig(), filter: Cafeteria.defaultPredicate, sortDescriptor: Cafeteria.sortDescriptor()) var cafeResults
    @ObservedResults(Building.self, configuration: abcConfig(), filter: Building.defaultPredicate, sortDescriptor: Building.sortDescriptor()) var buildingResults
    @ObservedResults(Org.self, configuration: abcConfig(), filter: Org.defaultPredicate, sortDescriptor: Org.sortDescriptor()) var orgResults
    @ObservedResults(FloorSpace.self, configuration: abcConfig(), filter: FloorSpace.defaultPredicate, sortDescriptor: FloorSpace.sortDescriptor()) var abcRoomResults
    @ObservedResults(FloorSpace.self, configuration: vwConfig(), filter: FloorSpace.defaultPredicate, sortDescriptor: FloorSpace.sortDescriptor()) var vwRoomResults
    @State private var query = ""

     var body: some View {
        NavigationSplitView {
            VStack {
                ScrollViewReader { value in
                    ScrollView {
                        LazyVStack(pinnedViews: .sectionHeaders) {
                            Section {
                                if noSearchResults() { // CRASH HERE: this calls @ObservedResult getters and throws fatal RLMException
                                    Text("No results found")
                                        .listRowSeparator(.hidden)
                                } else {
                                    searchResultsSection(favoriteSearchResults(), "Favorites", self)
                                    searchResultsSection(recentSearchResults(), "Recents", self)
                                    searchResultsSection(cafeteriaSearchResults(), "Cafeterias", self)
                                    buildingsSection(buildingResults.lazy, favorites, self, selectBuildingOnMap)
                                    roomsSection(roomResults(), favorites, self, selectRoomOnMap)
                                    searchResultsSection(orgSearchResults(), "Orgs", self)
                                    searchResultsSection(peopleSearchResults(), "People", self)
                                }
                            } header: {
                                Searchbar(query: $query, searchFocused: $searchFocus)
                                    .background(Color.background)
                                    .padding(EdgeInsets(top: 0, leading: 8, bottom: 4, trailing: 8))
                            }
                        }
                        .onChange(of: query) { _ in
                            if let firstResultId = firstResultId() {
                                value.scrollTo(firstResultId, anchor: .bottom)
                            }
                            Task { @MainActor in
                                filterSearchResults()
                            }
                        }
                    }
                }
            }
            .onAppear {
                if query.isEmpty {
                    $peopleResults.filter = search.defaultPeopleFilter
                    $cafeResults.filter = search.defaultCafeteriaFilter
                    $buildingResults.filter = search.defaultBuildingFilter
                    $orgResults.filter = Org.defaultPredicate
                    $abcRoomResults.filter = FloorSpace.defaultPredicate
                    $vwRoomResults.filter = FloorSpace.defaultPredicate
                } else {
                    filterSearchResults()
                }
        }
     }

    func noSearchResults() -> Bool {
        return favorites.isEmpty &&
        recents.isEmpty &&
        cafeResults.isEmpty &&
        buildingResults.isEmpty &&
        orgResults.isEmpty &&
        peopleResults.isEmpty &&
        abcRoomResults.isEmpty &&
        vwRoomResults.isEmpty
    }

    func filterSearchResults() {
        $favorites.filter = query.isEmpty ? nil : search.favoriteQuery(query)
        $recents.filter = query.isEmpty ? nil : search.recentsQuery(query)
        $cafeResults.filter = query.isEmpty ? Cafeteria.defaultPredicate : search.cafeQuery(query)
        $buildingResults.filter = query.isEmpty ? Building.defaultPredicate : search.buildingQuery(query)
        $abcRoomResults.filter = query.isEmpty ? FloorSpace.defaultPredicate : search.roomQuery(query)
        $vwRoomResults.filter = query.isEmpty ? FloorSpace.defaultPredicate : search.roomQuery(query)
        $orgResults.filter = query.isEmpty ? Org.defaultPredicate : search.orgQuery(query)
        $peopleResults.filter = query.isEmpty ? Person.defaultPredicate : search.peopleQuery(query)
    }

    static func userConfig() -> Realm.Configuration? {
        return RealmController.shared.userRealm?.configuration
    }

    static func abcConfig() -> Realm.Configuration? {
        return RealmController.shared.realm?.configuration
    }
}
tgoyne commented 1 year ago

https://github.com/realm/realm-core/pull/6411 might be related to this. It seems like something that'd cause problems very rarely, but could possibly cause freezing an object to throw a BadVersion exception.

drmarkpowell commented 1 year ago

I was finally yesterday able to reproduce the bug in development and it appears to stem from an invalid session authorization token being used to (re)initiate the Realm session.

To you question, I did try 10.38.0 and it did not address the issue.

I have a fix to prevent invalid access tokens from entering the workflow and we’re preparing to test it out.

On Apr 11, 2023, at 6:44 AM, Diana Perez Afanador @.***> wrote:

@drmarkpowell https://github.com/drmarkpowell we released a version (v10.38.0 https://github.com/realm/realm-swift/releases/tag/v10.38.0) with a possible fix for this, did you try the fix?, are you still getting this issue?

— Reply to this email directly, view it on GitHub https://github.com/realm/realm-swift/issues/8180#issuecomment-1503383238, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAH2GP4P3ICIFTMR2JAIIFLXAVN5HANCNFSM6AAAAAAWBT3X7I. You are receiving this because you were mentioned.

dianaafanador3 commented 1 year ago

@drmarkpowell thanks for getting back, let us know any update on the fix.

drmarkpowell commented 1 year ago

I just discovered that if a SwiftUI view is running and is listening to a ObservedResults and I call .invalidate() on the realm instance, this crash happens 100% of the time.

drmarkpowell commented 1 year ago

It seems likely that we found the cause of the error I got here. There was a path through our code that it could very occasionally take that called realm.invalidate() on the active realm during sign out and sign in. As this looked like it was not just unnecessary but also a bad idea altogether, I removed that from the code and deployed an update post-removal. So far this looks like it resolves our problem and I should know more early in the coming week.

On Apr 12, 2023, at 3:02 AM, Diana Perez Afanador @.***> wrote:

@drmarkpowell https://github.com/drmarkpowell thanks for getting back, let us know any update on the fix.

— Reply to this email directly, view it on GitHub https://github.com/realm/realm-swift/issues/8180#issuecomment-1505003100, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAH2GP5K3SXXIMDGPUSN5E3XAZ4UDANCNFSM6AAAAAAWBT3X7I. You are receiving this because you were mentioned.

dianaafanador3 commented 1 year ago

@drmarkpowell let us know if this completely solves your issue or if there is something we can do from our side.

drmarkpowell commented 1 year ago

Not calling invalidate() on the realm has solved it!The only thing I can think of to improve the SDK is to add more even more docs ( there are great docs already but always room to improve) for error handling and recovery, which I’ve already recommend to the docs team. Also, maybe a great big warning on invalidate() to not call it on a live Realm instance, ever, because it does bad things?Thanks for the help!On Apr 20, 2023, at 4:38 AM, Diana Perez Afanador @.***> wrote: @drmarkpowell let us know if this completely solves your issue or if there is something we can do from our side.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>