Impossible to catch Realm exceptions?

I’m not able to catch any major exceptions inside of Realm. Is this expected behavior? I can’t think of one exception that has gotten caught that I can remember. Thankfully permission ones seem where you write to a synced realm in a way you don’t have permission for do work fine. Here’s a code example:

        do {
            try realm.write {
                realm.delete(Task(ownerId: "asdf"))  // Throws of  course
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }

In this code I’d expect the write to fail and an error get caught and printed. Instead the app crashes due to an uncaught exception.

*** Terminating app due to uncaught exception ‘RLMException’, reason: ‘Can only delete an object from the Realm it belongs to.’

What can I do to fix this?

What kind of exceptions do get caught?

Thanks
-Jon

Super great question and they answer may not be so obvious, but here’s an attempt at a high level answer.

The Do-Catch syntax is designed to capture errors during program execution and help recover from them - and is really a Swift implementation.

What’s happening here is a programmer error - attempting to delete a non-managed object from a managed Realm is a pre-condition error and really, not recoverable. Attempting it again will produce the same error. e.g. it’s an ObjC exception due to a coding error, so fix your code

That being said the documentation (IMO) is pretty weak/vague on this; realm.write says things like:

and trying to begin a write transaction on a Realm which is already in a write transaction will throw an exception.

and

An NSError if the transaction could not be completed successfully. If block throws, the function throws the propagated ErrorType instead.

But it’s not clear under what conditions it will throw (pretty much none) or that its “throwing” is not what many of us consider “throwing” in a Swfit context.

So, in a nutshell, Realm doesn’t validate the quality of the data, just that its data.

That can get you into potential trouble: Given a Person has one property “name”; trying to populate it with “data” containing “field0” and “field1” is a valid call but what’s contained in “data” is not

let data = ["field0": "someId", "field1": "abcd"]
realm.create(Person.self, value: data, update: .error)

But, that will not “throw”, it will crash, so the code itself needs to be fixed. And really though, let’s do type safe calls as much as possible instead of relying on quoted strings.

So, in a nutshell, Do-Catch doesn’t Do-Catch with Realm.

Thanks much, Jay, that makes sense.

In the end I just want to react to errors correctly, so it would be helpful for the docs to list out what exceptions I should expect to catch and respond to. I’d like to get it right. :slight_smile: