9

I thought I was doing it correctly.

let realm = try! Realm()
do {
    try realm.write {
        realm.add(myObject)
    }
} catch {
    print("something went wrong!")
}

But I'm still getting a crash instead of that print statement. I'm not interested in avoiding the exception (in this case I caused it deliberately by adding an object with an existing primary key) but I want to be able to catch it and prevent a crash no matter what. Is this possible, and if so, how?

TimSim
  • 3,936
  • 7
  • 46
  • 83

1 Answers1

9

Realm Swift throws Objective-C exceptions only for things that are considered to be programmer error. These exceptions are not intended to be caught and handled at runtime as they're indicative of an error in the program that must be fixed.

bdash
  • 18,110
  • 1
  • 59
  • 91
  • Violating a precondition is one example of a programmer error. The other category of errors are runtime errors. These are errors that can occur even with correctly written code and that must be handled at runtime (i.e., file not found, out of disk space, etc). – bdash May 10 '20 at 22:31
  • The documentation for primary keys state they must be unique. – bdash May 10 '20 at 22:48
  • Yeah it says it must be unique. Nothing in the docs say anything about write. I checked both `write` and `add`. If people went by your logic, there's no runtime error. File should be searched before it is accessed. Disk space should be checked before files are written. – funct7 May 10 '20 at 22:49
  • Compare it with Apple docs: `A call to this function must balance a call to enter(). It is invalid to call it more times than enter(), which would result in a negative count.` Clearly states something is invalid. – funct7 May 10 '20 at 22:54
  • If you’re not happy with Realm’s documentation, by all means file an issue with them about it. You’re wrong about there not being a difference between programmer error (precondition violations, API misuse, etc) and runtime errors. It’s impossible to safely check for files existence or disk space before you take action because whatever state you observe can change before you take action, making it impossible to avoid runtime errors. – bdash May 10 '20 at 22:55
  • I knew you were going to argue as such. Most of the time you can safely check it. Especially if it's being written in the sandbox, which is... wait enforced by iOS anyways. Don't bring really really really exceptional situations and argue that it should be the norm. Also, if the documentation didn't state it, it's not in the contract. – funct7 May 10 '20 at 22:58
  • Attempting to perform checks like you describe is a common cause of security issues (https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use). Even if you do check preemptively, you still have to handle the runtime error in order to avoid security and correctness problems, so at that point there’s very little reason to bother with the preemptive check. – bdash May 10 '20 at 23:01
  • Yeah, for some reason, Android doesn't think a unique constraint failure is a cause to kill an app. `android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed` – funct7 May 10 '20 at 23:03
  • Yeah someone is arguing a failure to meet a constraint is a good reason to kill an app. I'm saying it's not. Looks like other platforms might agree with me. "Just looking to argue" sounds just about right. Also not stating something in the contract but arguing it's broken is perfect logic. – funct7 May 10 '20 at 23:07
  • I’ve explained that Realm makes a distinction between programmer error and runtime errors, with the former not being recoverable. You can disagree with their design all you want, but if you use Realm you need to understand it and write your code accordingly. Ranting at me isn’t going to change anything. If you feel very strongly about it, take it up with Realm’s developers. – bdash May 10 '20 at 23:16
  • I actually did comment in their Github issues. I'm arguing inserting an object that breaks a database constraint is bound to happen and should not be considered a programmer error. Also, if it really must be a programmer error, the documentation on the method should clearly state that fact instead of being implicitly understood. – funct7 May 10 '20 at 23:51