realm-kotlin icon indicating copy to clipboard operation
realm-kotlin copied to clipboard

NullPointerException in freezeWriteReturnValue function Line 144 in test runBlocking

Open XandrMaster opened this issue 3 years ago • 1 comments

Hello guys . I found another NullPointerException in this code line L144 . The stack is following : java.lang.NullPointerException at io.realm.kotlin.internal.SuspendableWriter.freezeWriteReturnValue(SuspendableWriter.kt:144) at io.realm.kotlin.internal.SuspendableWriter.access$freezeWriteReturnValue(SuspendableWriter.kt:47) at io.realm.kotlin.internal.SuspendableWriter$write$2.invokeSuspend(SuspendableWriter.kt:130) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.os.HandlerThread.run(HandlerThread.java:67)

There is my test repo and last commit for reproduce that issue .
So this function works fine , but this one with runBlocking cause to Exception :( . For iOs test the same Exception . But call the same function from Activity coroutines also works fine . The problem in the tests. Maybe am I doing something wrong ? Thanks for help an advance !

XandrMaster avatar Aug 10 '22 09:08 XandrMaster

I use runBlocking in tests , because I call suspended functions in My real project.

XandrMaster avatar Aug 10 '22 10:08 XandrMaster

Hi @XandrMaster, thank you for this. I can reproduce this.

The problem looks like it is here:

	fun deleteBooks() {
		realm.writeBlocking {
			query(Book::class).first().find()?.apply {
				delete(this)
			}
		}
	}

Our write methods return the last value from the closure, but in this case you are returning a deleted object. This is a bug on our end. You can fix it by doing this instead:

	fun deleteBooks() {
		realm.writeBlocking {
			query(Book::class).first().find()?.apply {
				delete(this)
			}
                         Unit
		}
	}

cmelchior avatar Aug 15 '22 06:08 cmelchior

A few other comments:

	fun createBook(name: String, description: String): Book {
		val book = Book().apply {
			this.name = name
			this.description = description
		}

		realm.writeBlocking {
			copyToRealm(book)
		}

		return book
	}

Should probably be:


	fun createBook(name: String, description: String): Book {
		val book = Book().apply {
			this.name = name
			this.description = description
		}

		return realm.writeBlocking {
			copyToRealm(book)
		}
	}

Otherwise, you don't return the created object.

Also, it is unclear why you are using writeBlocking(). If everything is running inside coroutines, I would probably use realm.write instead.

cmelchior avatar Aug 15 '22 06:08 cmelchior