1

I have the following code I'm trying to debug and want to add a try/catch block to see why it is crashing. When I add that though, it gives me an unresolved reference a few lines down, as noted in the code comments. What can I do to get around that, please?

private val appServiceInstance by lazy {
    // If logs are on app level then it set for everything ..
    val configuration =
        AppConfiguration.Builder("application-0-rpbsh")
            .log(LogLevel.ALL).build()

    try{
        App.create(configuration)  //When try/catch added around this, the issue happens
    }
    catch (e: Exception) {
        Logger.e("Exception caught: " + e.message)
        Logger.e(e.stackTraceToString())
    }

}

init {
    if (!initialized) {
        setupRealmSync()
        initialized = true
    } else {
        throw IllegalStateException("Singleton instance already created.")
    }
}
private fun setupRealmSync() {
    val user = runBlocking { appServiceInstance.currentUser!! } //Unresolved Reference happens here on currentUser
    val config = SyncConfiguration
        .Builder(
            user,
            setOf(UserAccount::class,Pellet::class, PelletInsertionVisit::class, PelletLot::class, Patient::class,
                Practice::class )
        )
        .initialSubscriptions(rerunOnOpen = true) { realms ->
            add(
                realms.query<PelletInsertionVisit>(),
                name = "patient info",
                updateExisting = true
            )
            add(realms.query<PelletLot>(), name = "Pallet info", updateExisting = true)
            add(realms.query<Patient>(), name = "Patient info", updateExisting = true)
            add(realms.query<Practice>(), name = "Practice info", updateExisting = true)
            add(realms.query<UserAccount>(), name = "UserAccount info", updateExisting = true)

        }
        .build()
    realm = Realm.open(config)
}
7
  • An unresolved reference to what?
    – nitind
    Commented Jul 9 at 18:33
  • 2
    It certainly wasn't the best question seen to date, but it was clear enough to me to understand what the problem was. In fact, I was just writing an answer when the question was being closed...
    – Leviathan
    Commented Jul 9 at 18:48
  • Not to go through the hassle of reopening the question I try to answer it in the comments. To make it short: The lazy lambda needs a return value. Previously, it was App.create(configuration), now it is a combination of that and the result of the catch block, which doesn't exist, hence the error. If you re-throw the exception in the catch block after logging it should work again: throw e
    – Leviathan
    Commented Jul 9 at 18:48
  • 1
    Shouldn’t have been closed. No necessary details are missing.
    – Tenfour04
    Commented Jul 9 at 21:34
  • 1
    Not sure why it was closed for more information. You just have to scroll to the right to see what I think people were missing. Anyway, doing the throw e worked perfectly and it makes sense. Thank you!
    – user443654
    Commented Jul 9 at 22:19

1 Answer 1

3

TL;DR

Add throw e at the end of the catch block.

Explanation

appServiceInstance is initialized by the return value of the lazy lambda. Without the try/catch that is whatever App.create(configuration) returns. Let's assume that is an object of type App. Everything works as intended.

Now, when you wrap that with try/catch the return value is either the result of the successful try block (an App object), or it is the result of the catch block when an exception occurs. The catch block, however, only logs and therefore just returns Unit. That means the combined try/catch returns the common super type of App and Unit: That is Any. In consequnce appServiceInstance is not of type App anymore, it is now of type Any.

That works so far, but since the type of appServiceInstance isn't App anymore, the rest of your code that accesses its properties will now produce a compile error because Any doesn't have these properties.

The solution is to prevent the catch block from changing the type of appServiceInstance. Since you probably can't/don't want to provide another App object in case an exception occurred you need to prevent the catch block from returning anything at all, not even Unit. The easiest way is to just rethrow the exception you just logged:

catch (e: Exception) {
    Logger.e("Exception caught: " + e.message)
    Logger.e(e.stackTraceToString())
    throw e
}

Without the catch block returning the return type of the combined try/catch is just App - as it was before you added the try/catch.

Everything should work again.

Not the answer you're looking for? Browse other questions tagged or ask your own question.