@mentra/crust 3.3.0-dev.839 → 3.3.0-dev.841
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -58,3 +58,11 @@ shutdown cancels only that module's outstanding host requests.
|
|
|
58
58
|
|
|
59
59
|
Engine callers use the ordinary cloud-client API with a signal. They do not call
|
|
60
60
|
native start/cancel methods or maintain their own request registry.
|
|
61
|
+
|
|
62
|
+
Android native HTTP failures carry fixed `E_NATIVE_HTTP_*` codes for DNS,
|
|
63
|
+
connection, timeout, TLS, socket, interrupted I/O, generic I/O, or other failures.
|
|
64
|
+
The cloud client records only those allowlisted codes in its existing network
|
|
65
|
+
warning; report submission still rejects with `NETWORK_ERROR`. Exception text,
|
|
66
|
+
URLs, credentials and stacks are not copied into that warning. These categories
|
|
67
|
+
describe a failed request; they do not establish the phone's network routing or
|
|
68
|
+
why its Internet connection was unavailable.
|
|
@@ -23,6 +23,7 @@ import com.mentra.crust.jsc.JSCRuntime
|
|
|
23
23
|
import com.mentra.crust.jsc.InstalledMiniappManifest
|
|
24
24
|
import com.mentra.crust.jsc.JSCPolyfillBridge
|
|
25
25
|
import com.mentra.crust.http.NativeHttpRequests
|
|
26
|
+
import com.mentra.crust.http.nativeHttpFailureCode
|
|
26
27
|
|
|
27
28
|
class CrustModule : Module() {
|
|
28
29
|
companion object {
|
|
@@ -210,7 +211,7 @@ class CrustModule : Module() {
|
|
|
210
211
|
)
|
|
211
212
|
)
|
|
212
213
|
},
|
|
213
|
-
onError = { error -> promise.reject(
|
|
214
|
+
onError = { error -> promise.reject(nativeHttpFailureCode(error), error.message ?: "Native HTTP request failed", error) },
|
|
214
215
|
)
|
|
215
216
|
}
|
|
216
217
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
package com.mentra.crust.http
|
|
2
|
+
|
|
3
|
+
import java.io.IOException
|
|
4
|
+
import java.io.InterruptedIOException
|
|
5
|
+
import java.net.ConnectException
|
|
6
|
+
import java.net.NoRouteToHostException
|
|
7
|
+
import java.net.SocketException
|
|
8
|
+
import java.net.SocketTimeoutException
|
|
9
|
+
import java.net.UnknownHostException
|
|
10
|
+
import javax.net.ssl.SSLException
|
|
11
|
+
|
|
12
|
+
/** Fixed diagnostic codes only: exception messages can contain private URLs and addresses. */
|
|
13
|
+
internal fun nativeHttpFailureCode(error: Throwable): String {
|
|
14
|
+
var current: Throwable? = error
|
|
15
|
+
var fallback = "E_NATIVE_HTTP_OTHER"
|
|
16
|
+
// Native wrappers can retain the useful cause. Bound traversal even for a cyclic cause chain.
|
|
17
|
+
repeat(8) {
|
|
18
|
+
val cause = current ?: return fallback
|
|
19
|
+
when (cause) {
|
|
20
|
+
is UnknownHostException -> return "E_NATIVE_HTTP_DNS"
|
|
21
|
+
is SocketTimeoutException -> return "E_NATIVE_HTTP_TIMEOUT"
|
|
22
|
+
is SSLException -> return "E_NATIVE_HTTP_TLS"
|
|
23
|
+
is ConnectException, is NoRouteToHostException -> return "E_NATIVE_HTTP_CONNECT"
|
|
24
|
+
is SocketException -> return "E_NATIVE_HTTP_SOCKET"
|
|
25
|
+
is InterruptedIOException -> return "E_NATIVE_HTTP_INTERRUPTED"
|
|
26
|
+
is IOException -> fallback = "E_NATIVE_HTTP_IO"
|
|
27
|
+
}
|
|
28
|
+
current = cause.cause
|
|
29
|
+
}
|
|
30
|
+
return fallback
|
|
31
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package com.mentra.crust.http
|
|
2
|
+
|
|
3
|
+
import java.io.IOException
|
|
4
|
+
import java.io.InterruptedIOException
|
|
5
|
+
import java.net.ConnectException
|
|
6
|
+
import java.net.NoRouteToHostException
|
|
7
|
+
import java.net.SocketException
|
|
8
|
+
import java.net.SocketTimeoutException
|
|
9
|
+
import java.net.UnknownHostException
|
|
10
|
+
import javax.net.ssl.SSLHandshakeException
|
|
11
|
+
import org.junit.Assert.assertEquals
|
|
12
|
+
import org.junit.Test
|
|
13
|
+
|
|
14
|
+
class NativeHttpFailureTest {
|
|
15
|
+
@Test fun `preserves failure category without exception text`() {
|
|
16
|
+
val privateMessage = "https://private.example?token=secret SSID private-address"
|
|
17
|
+
val cases = listOf(
|
|
18
|
+
UnknownHostException(privateMessage) to "E_NATIVE_HTTP_DNS",
|
|
19
|
+
ConnectException(privateMessage) to "E_NATIVE_HTTP_CONNECT",
|
|
20
|
+
NoRouteToHostException(privateMessage) to "E_NATIVE_HTTP_CONNECT",
|
|
21
|
+
SocketTimeoutException(privateMessage) to "E_NATIVE_HTTP_TIMEOUT",
|
|
22
|
+
SSLHandshakeException(privateMessage) to "E_NATIVE_HTTP_TLS",
|
|
23
|
+
SocketException(privateMessage) to "E_NATIVE_HTTP_SOCKET",
|
|
24
|
+
InterruptedIOException(privateMessage) to "E_NATIVE_HTTP_INTERRUPTED",
|
|
25
|
+
IOException(privateMessage) to "E_NATIVE_HTTP_IO",
|
|
26
|
+
IllegalStateException(privateMessage) to "E_NATIVE_HTTP_OTHER",
|
|
27
|
+
)
|
|
28
|
+
cases.forEach { (error, expected) -> assertEquals(expected, nativeHttpFailureCode(error)) }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Test fun `retains a specific cause inside a generic native wrapper`() {
|
|
32
|
+
val wrapped = IOException("private wrapper", UnknownHostException("private hostname"))
|
|
33
|
+
assertEquals("E_NATIVE_HTTP_DNS", nativeHttpFailureCode(wrapped))
|
|
34
|
+
assertEquals("E_NATIVE_HTTP_IO", nativeHttpFailureCode(IllegalStateException(IOException("private"))))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Test fun `never parses a category from private error text and bounds cyclic causes`() {
|
|
38
|
+
assertEquals("E_NATIVE_HTTP_OTHER", nativeHttpFailureCode(Exception("E_NATIVE_HTTP_DNS")))
|
|
39
|
+
val first = Exception("private one")
|
|
40
|
+
val second = Exception("private two", first)
|
|
41
|
+
first.initCause(second)
|
|
42
|
+
assertEquals("E_NATIVE_HTTP_OTHER", nativeHttpFailureCode(first))
|
|
43
|
+
}
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mentra/crust",
|
|
3
|
-
"version": "3.3.0-dev.
|
|
3
|
+
"version": "3.3.0-dev.841",
|
|
4
4
|
"description": "Mentra Native Module",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"license": "Apache-2.0",
|
|
36
36
|
"homepage": "https://github.com/Mentra-Community/MentraOS/tree/dev/mobile/modules/crust#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@mentra/jspolyfill": "3.3.0-dev.
|
|
38
|
+
"@mentra/jspolyfill": "3.3.0-dev.841"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@expo/config-plugins": ">=8.0.0",
|