






























@@ -64,6 +64,7 @@ data class GatewayConnectErrorDetails(
6464val code: String?,
6565val canRetryWithDeviceToken: Boolean,
6666val recommendedNextStep: String?,
67+val pauseReconnect: Boolean? = null,
6768val reason: String? = null,
6869)
6970@@ -736,6 +737,7 @@ class GatewaySession(
736737 code = it["code"].asStringOrNull(),
737738 canRetryWithDeviceToken = it["canRetryWithDeviceToken"].asBooleanOrNull() == true,
738739 recommendedNextStep = it["recommendedNextStep"].asStringOrNull(),
740+ pauseReconnect = it["pauseReconnect"].asBooleanOrNull(),
739741 reason = it["reason"].asStringOrNull(),
740742 )
741743 }
@@ -1040,20 +1042,17 @@ class GatewaySession(
10401042 detailCode == "AUTH_TOKEN_MISMATCH"
10411043 }
104210441043-private fun shouldPauseReconnectAfterAuthFailure(error: ErrorShape): Boolean =
1044-when (error.details?.code) {
1045-"AUTH_TOKEN_MISSING",
1046-"AUTH_BOOTSTRAP_TOKEN_INVALID",
1047-"AUTH_PASSWORD_MISSING",
1048-"AUTH_PASSWORD_MISMATCH",
1049-"AUTH_RATE_LIMITED",
1050-"PAIRING_REQUIRED",
1051-"CONTROL_UI_DEVICE_IDENTITY_REQUIRED",
1052-"DEVICE_IDENTITY_REQUIRED",
1053--> true
1054-"AUTH_TOKEN_MISMATCH" -> deviceTokenRetryBudgetUsed && !pendingDeviceTokenRetry
1055-else -> false
1056- }
1045+private fun shouldPauseReconnectAfterAuthFailure(error: ErrorShape): Boolean {
1046+val target = desired
1047+return shouldPauseGatewayReconnectAfterAuthFailure(
1048+ error = error,
1049+ hasBootstrapToken = target?.bootstrapToken?.trim()?.isNotEmpty() == true,
1050+ role = target?.options?.role,
1051+ scopes = target?.options?.scopes ?: emptyList(),
1052+ deviceTokenRetryBudgetUsed = deviceTokenRetryBudgetUsed,
1053+ pendingDeviceTokenRetry = pendingDeviceTokenRetry,
1054+ )
1055+ }
1057105610581057private fun shouldClearStoredDeviceTokenAfterRetry(error: ErrorShape): Boolean = error.details?.code == "AUTH_DEVICE_TOKEN_MISMATCH"
10591058@@ -1068,6 +1067,36 @@ class GatewaySession(
10681067 }
10691068}
107010691070+internal fun shouldPauseGatewayReconnectAfterAuthFailure(
1071+error: GatewaySession.ErrorShape,
1072+hasBootstrapToken: Boolean,
1073+role: String?,
1074+scopes: List<String>,
1075+deviceTokenRetryBudgetUsed: Boolean,
1076+pendingDeviceTokenRetry: Boolean,
1077+): Boolean =
1078+when (error.details?.code) {
1079+"AUTH_TOKEN_MISSING",
1080+"AUTH_BOOTSTRAP_TOKEN_INVALID",
1081+"AUTH_PASSWORD_MISSING",
1082+"AUTH_PASSWORD_MISMATCH",
1083+"AUTH_RATE_LIMITED",
1084+"CONTROL_UI_DEVICE_IDENTITY_REQUIRED",
1085+"DEVICE_IDENTITY_REQUIRED",
1086+-> true
1087+"PAIRING_REQUIRED" ->
1088+!(
1089+ hasBootstrapToken &&
1090+ role?.trim() == "node" &&
1091+ scopes.isEmpty() &&
1092+ error.details.reason == "not-paired" &&
1093+ (error.details.pauseReconnect == false ||
1094+ error.details.recommendedNextStep == "wait_then_retry")
1095+ )
1096+"AUTH_TOKEN_MISMATCH" -> deviceTokenRetryBudgetUsed && !pendingDeviceTokenRetry
1097+else -> false
1098+ }
1099+10711100internal fun buildGatewayWebSocketUrl(
10721101host: String,
10731102port: Int,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。