diff --git a/native/kotlin/api/kotlin/src/integrationTest/kotlin/ApiUrlDiscoveryTest.kt b/native/kotlin/api/kotlin/src/integrationTest/kotlin/ApiUrlDiscoveryTest.kt index 7dcce7e77..4492b3f41 100644 --- a/native/kotlin/api/kotlin/src/integrationTest/kotlin/ApiUrlDiscoveryTest.kt +++ b/native/kotlin/api/kotlin/src/integrationTest/kotlin/ApiUrlDiscoveryTest.kt @@ -27,6 +27,15 @@ import kotlin.test.assertContains class ApiUrlDiscoveryTest { private val loginClient: WpLoginClient = WpLoginClient() + @Test + fun testLocalSite() = runTest { + assertEquals( + "http://localhost/wp-admin/authorize-application.php", + loginClient.apiDiscovery("http://localhost") + .assertSuccess().applicationPasswordsAuthenticationUrl.url() + ) + } + @Test // Spec Example 1 fun testValidSiteWorksCorrectly() = runTest { assertEquals( diff --git a/native/kotlin/api/kotlin/src/main/kotlin/rs/wordpress/api/kotlin/WpRequestExecutor.kt b/native/kotlin/api/kotlin/src/main/kotlin/rs/wordpress/api/kotlin/WpRequestExecutor.kt index 149ead33e..eb7cb913d 100644 --- a/native/kotlin/api/kotlin/src/main/kotlin/rs/wordpress/api/kotlin/WpRequestExecutor.kt +++ b/native/kotlin/api/kotlin/src/main/kotlin/rs/wordpress/api/kotlin/WpRequestExecutor.kt @@ -25,6 +25,7 @@ import uniffi.wp_api.WpNetworkRequest import uniffi.wp_api.WpNetworkResponse import uniffi.wp_api.parseCertificate import java.io.File +import java.net.ConnectException import java.net.NoRouteToHostException import java.net.UnknownHostException import javax.net.ssl.HttpsURLConnection @@ -130,7 +131,9 @@ class WpRequestExecutor( ) } - @Suppress("ThrowsCount") + // We intentionally catch all exceptions to prevent UniFFI callback crashes. + // All exceptions are converted to proper Rust error types rather than being swallowed. + @Suppress("ThrowsCount", "TooGenericExceptionCaught", "SwallowedException") private fun executeRequestSafely( urlRequest: Request, requestUrl: String, @@ -162,6 +165,18 @@ class WpRequestExecutor( throw requestExecutionFailedWith(RequestExecutionErrorReason.unknownHost(e)) } catch (e: NoRouteToHostException) { throw requestExecutionFailedWith(RequestExecutionErrorReason.noRouteToHost(e)) + } catch (e: ConnectException) { + throw requestExecutionFailedWith( + RequestExecutionErrorReason.HttpError( + reason = "Connection failed: ${e.localizedMessage}" + ) + ) + } catch (e: Exception) { + throw requestExecutionFailedWith( + RequestExecutionErrorReason.GenericError( + errorMessage = e.localizedMessage ?: e.toString() + ) + ) } }