Skip to content

Commit

Permalink
Fix network requests sometimes returning null instead of either ret…
Browse files Browse the repository at this point in the history
…urning success or failure
  • Loading branch information
Christian Melchior committed Oct 11, 2023
1 parent 047708f commit f559459
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
### Fixed
* Realm objects accessors behave as an unmanaged object after an incremental build. (Issue [#7844](https://github.com/realm/realm-java/pull/7844))
* [RealmApp] Crash when opening a Realm with a proxy enabled. (Issue [#7828](https://github.com/realm/realm-java/issues/7828))
* [RealmApp] It was possible to create a `User` object with invalid state that would throw a `NullPointerException` when accessed. (Issue [#7847](https://github.com/realm/realm-java/issues/7847))

### Compatibility
* File format: Generates Realms with format v23. Unsynced Realms will be upgraded from Realm Java 2.0 and later. Synced Realms can only be read and upgraded if created with Realm Java v10.0.0-BETA.1.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.realm.internal.network

import androidx.test.platform.app.InstrumentationRegistry
import io.realm.Realm
import io.realm.mongodb.App
import io.realm.mongodb.AppException
import io.realm.mongodb.ErrorCode
import junit.framework.TestCase.assertEquals
import org.junit.Before
import org.junit.Test
import kotlin.test.assertFailsWith

class NetworkRequestTests {

private lateinit var app: App

@Before
fun setUp() {
Realm.init(InstrumentationRegistry.getInstrumentation().targetContext)
}

// Test for https://github.com/realm/realm-java/issues/7847
@Test
fun interruptedRequestReturnsError() {
val request = object: NetworkRequest<Unit>() {
override fun mapSuccess(result: Any?): Unit {
Unit
}

override fun execute(callback: NetworkRequest<Unit>) {
Thread.currentThread().interrupt()
}
}
assertFailsWith<AppException> {
request.resultOrThrow()
}.also {
assertEquals(it.errorCode, ErrorCode.NETWORK_INTERRUPTED)
assertEquals(it.errorMessage, "Network request interrupted.")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ public abstract class NetworkRequest<T> extends OsJavaNetworkTransport.NetworkTr
@Override
public void onSuccess(Object result) {
T mappedResult = mapSuccess(result);
if (success != null) {
success.set(mappedResult);
}
success.set(mappedResult);
latch.countDown();
}

Expand Down Expand Up @@ -87,23 +85,19 @@ public T resultOrThrow() {

execute(this);
try {
// Wait indefinitely. Timeouts should be handled by the Network layer,
// so will eventually bubble up as an exception.
// Wait indefinitely. Timeouts should be handled by the Network layer, otherwise
// it can be interrupted manually by calling `RealmAsyncTask.cancel()`
latch.await();
} catch (InterruptedException e) {
RealmLog.debug("Network request interrupted.");
error.set(new AppException(ErrorCode.NETWORK_INTERRUPTED, "Network request interrupted."));
}

// Result of request should be available. Throw if an error happened, otherwise return
// the result.
if (error.get() != null) {
throw error.get();
} else {
if (success != null) {
return success.get();
} else {
return null;
}
return success.get();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

/**
* Specialized case of {@link NetworkRequest} where we are not interested in the response value,
* just wether or not the request succeeded.
* just whether or not the request succeeded.
*/
public abstract class VoidNetworkRequest extends NetworkRequest<Void> {

Expand Down

0 comments on commit f559459

Please sign in to comment.