SwiftLint: Realm force try error

https://realm.io/docs/swift/latest/

// Persist your data easily
let realm = try! Realm()
try! realm.write {
  realm.add(mydog)
}

I get the following error: error: Force Try Violation: Force tries should be avoided. (force_try)

Its kind of ironic that Realm’s first example in docs does not work with swiftlint.

Not sure if I needed to open this issue here or somewhere else

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 20 (2 by maintainers)

Most upvoted comments

Does anybody else find it ironic that SwiftLint is maintained by Realm, and Realm’s own code violates the SwiftLint guidelines?

Does anybody else find it ironic that SwiftLint is maintained by Realm, and Realm’s own code violates the SwiftLint guidelines?

I thought this went without saying, but clearly there’s confusion here that I should address. SwiftLint provides stylistic hints, and there will always be a decent amount of “false positives” in a linter. Otherwise, if the rule applied 100% of the time, that syntax would be disallowed by the compiler.

In the case of Realm, there are language limitations in Swift that prevent the ideal use of context-sensitive error handling that Realm would ideally benefit from. Realm’s error handling model is explained in the official docs. There’s a leaky abstraction there since the initializer can only fail in specific circumstances (e.g. first time it is invoked on a new thread) and Swift doesn’t have a concept of errors that can only occurs in specific circumstances. Either something always or never throws. So Realm’s use of try! is appropriate when you’re familiar with these semantics. That being said, try! is still a code smell (read, not an absolute error to be avoided at all costs), so SwiftLint reports it as such.

try! is a useful assertion, saying “hey Swift compiler, I know you think this can error, but I know better in this circumstance”. When in doubt if an error can or cannot occur, sure handle errors. But otherwise, you owe it to yourself and your future codebase maintainers to document the expected flow of your program.

SwiftLint is designed to be overruled by a human when the human knows better than the tool. Use // swiftlint:disable liberally. Don’t make your code worse to please SwiftLint.

I wasn’t suggesting that it was bad or anything. Was just pointing out that I had to change .yml settings to compile Realm’s example code. Which wasn’t a good experience.

Maybe inside the rules, you could implement a default ignore for Realm related try! calls.

I agree. This should either be a warning or the Realm examples should be rewritten with compliant syntax. I just started with SwiftLint and the first errors I get are based on this and on my line lengths. Neither should break my build.

I strongly discourage moving Realm creation to a singleton, as that would bypass Realm’s thread-specific creation logic. Sounds like a preferable solution would be to wrap Realm creation in a function that handles the common error handling you want to perform.

I just realised your issue with this 😃 a bit annoying I agree.

To be honest for specifically Realm I have a wrapper similar to

public class MyRealms {
    /// swiftlint:disable:next force_try
    public static var main: Realm = try! Realm(configuration: ...)
}

/// Other file
do {
    try MyRealms.main.write { 

    } catch let err { 
        /// Some write error
    } 
}

That way I can just use MyRealms.realm.write or whichever and get rid of all of the warnings.

About writes etc, I would usually wrap those in a do/catch, just in case. so never had an issues with it.

This is just one thought of a way to go around this without disabling force_try on your entire code base, since it is a good lint rule in general 😃

By the way this seems more like a complaint for realm/Realm then realm/SwiftLint 😃