Skip to content

Commit 62cbc5e

Browse files
authored
Fix exception handling in Kotlin request executor (#1025)
Added comprehensive exception handling to prevent UnexpectedUniFFICallbackError crashes when network exceptions occur. The executor now properly catches and maps all exceptions to appropriate Rust error types. Without proper exception handling, uncaught exceptions from OkHttp would crash the UniFFI callback layer instead of being returned as proper errors to Rust. This was causing API discovery and other network operations to fail with UnexpectedUniFFICallbackError instead of meaningful error messages. Changes: - Add ConnectException handler to map connection failures to HttpError - Add catch-all Exception handler to map unexpected errors to GenericError - Add testLocalSite integration test to verify localhost API discovery works
1 parent 3d2dafd commit 62cbc5e

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

native/kotlin/api/kotlin/src/integrationTest/kotlin/ApiUrlDiscoveryTest.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ import kotlin.test.assertContains
2727
class ApiUrlDiscoveryTest {
2828
private val loginClient: WpLoginClient = WpLoginClient()
2929

30+
@Test
31+
fun testLocalSite() = runTest {
32+
assertEquals(
33+
"http://localhost/wp-admin/authorize-application.php",
34+
loginClient.apiDiscovery("http://localhost")
35+
.assertSuccess().applicationPasswordsAuthenticationUrl.url()
36+
)
37+
}
38+
3039
@Test // Spec Example 1
3140
fun testValidSiteWorksCorrectly() = runTest {
3241
assertEquals(

native/kotlin/api/kotlin/src/main/kotlin/rs/wordpress/api/kotlin/WpRequestExecutor.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import uniffi.wp_api.WpNetworkRequest
2525
import uniffi.wp_api.WpNetworkResponse
2626
import uniffi.wp_api.parseCertificate
2727
import java.io.File
28+
import java.net.ConnectException
2829
import java.net.NoRouteToHostException
2930
import java.net.UnknownHostException
3031
import javax.net.ssl.HttpsURLConnection
@@ -130,7 +131,9 @@ class WpRequestExecutor(
130131
)
131132
}
132133

133-
@Suppress("ThrowsCount")
134+
// We intentionally catch all exceptions to prevent UniFFI callback crashes.
135+
// All exceptions are converted to proper Rust error types rather than being swallowed.
136+
@Suppress("ThrowsCount", "TooGenericExceptionCaught", "SwallowedException")
134137
private fun executeRequestSafely(
135138
urlRequest: Request,
136139
requestUrl: String,
@@ -162,6 +165,18 @@ class WpRequestExecutor(
162165
throw requestExecutionFailedWith(RequestExecutionErrorReason.unknownHost(e))
163166
} catch (e: NoRouteToHostException) {
164167
throw requestExecutionFailedWith(RequestExecutionErrorReason.noRouteToHost(e))
168+
} catch (e: ConnectException) {
169+
throw requestExecutionFailedWith(
170+
RequestExecutionErrorReason.HttpError(
171+
reason = "Connection failed: ${e.localizedMessage}"
172+
)
173+
)
174+
} catch (e: Exception) {
175+
throw requestExecutionFailedWith(
176+
RequestExecutionErrorReason.GenericError(
177+
errorMessage = e.localizedMessage ?: e.toString()
178+
)
179+
)
165180
}
166181
}
167182

0 commit comments

Comments
 (0)