Bug: Support translations for Cookie Acquisition error (#6917)

This commit is contained in:
David Perez
2026-05-13 15:05:53 -05:00
committed by GitHub
parent 8fe23ad275
commit e4f030d0e3
17 changed files with 94 additions and 31 deletions

View File

@@ -13,6 +13,5 @@ import java.io.IOException
*/
class CookieRedirectException(
val hostname: String,
) : IOException(
"Your request was interrupted because the app needed to re-authenticate. Please try again.",
)
message: String,
) : IOException(message)

View File

@@ -60,7 +60,10 @@ internal class CookieInterceptor(
if (cookieProvider.needsBootstrap(hostname)) {
Timber.d("Cookie bootstrap required for $hostname, triggering acquisition")
cookieProvider.acquireCookies(hostname)
throw CookieRedirectException(hostname = hostname)
throw CookieRedirectException(
hostname = hostname,
message = cookieProvider.errorMessageString,
)
}
val request = originalRequest.withCookies(hostname)
@@ -77,6 +80,7 @@ internal class CookieInterceptor(
cookieProvider.acquireCookies(hostname)
throw CookieRedirectException(
hostname = hostname,
message = cookieProvider.errorMessageString,
)
}

View File

@@ -10,6 +10,11 @@ import com.bitwarden.network.model.NetworkCookie
* Bitwarden API endpoints behind a load balancer.
*/
interface CookieProvider {
/**
* The translated human-readable string to be displayed when the missing cookie is the reason
* for a request failure.
*/
val errorMessageString: String
/**
* Determines if the given [hostname] requires cookie bootstrap.

View File

@@ -66,6 +66,7 @@ class CookieInterceptorTest {
val chain = FakeInterceptorChain(originalRequest)
every { mockCookieProvider.needsBootstrap("vault.bitwarden.com") } returns true
every { mockCookieProvider.errorMessageString } returns "Error"
val exception = assertThrows<CookieRedirectException> {
interceptor.intercept(chain)
@@ -159,6 +160,7 @@ class CookieInterceptorTest {
every { mockCookieProvider.needsBootstrap("vault.bitwarden.com") } returns false
every { mockCookieProvider.getCookies("vault.bitwarden.com") } returns emptyList()
every { mockCookieProvider.errorMessageString } returns "Error"
val exception = assertThrows<CookieRedirectException> {
interceptor.intercept(chain)
@@ -224,6 +226,7 @@ class CookieInterceptorTest {
every { mockCookieProvider.needsBootstrap("vault.bitwarden.com") } returns false
every { mockCookieProvider.getCookies("vault.bitwarden.com") } returns cookies
every { mockCookieProvider.errorMessageString } returns "Error"
val exception = assertThrows<CookieRedirectException> {
interceptor.intercept(chain)

View File

@@ -13,7 +13,7 @@ class BitwardenErrorTest {
@Test
fun `toBitwardenError with CookieRedirectException should return Http with status 400`() {
val exception = CookieRedirectException(hostname = "example.com")
val exception = CookieRedirectException(hostname = "example.com", message = "Fail!")
val result = exception.toBitwardenError()
@@ -24,13 +24,15 @@ class BitwardenErrorTest {
@Test
fun `toBitwardenError with CookieRedirectException should include message in body`() {
val exception = CookieRedirectException(hostname = "example.com")
val message = "Your request was interrupted because " +
"the app needed to re-authenticate. Please try again."
val exception = CookieRedirectException(hostname = "example.com", message = message)
val result = exception.toBitwardenError()
val httpError = result as BitwardenError.Http
val body = httpError.responseBodyString
assertTrue(body?.contains(exception.message.orEmpty()) == true)
assertTrue(body?.contains(message) == true)
}
@Test

View File

@@ -24,7 +24,7 @@ class ExceptionExtensionsTest {
fun `parseErrorBodyOrNull with CookieRedirectException should extract message`() {
val expectedMessage = "Your request was interrupted because the app " +
"needed to re-authenticate. Please try again."
val error = CookieRedirectException(hostname = "example.com")
val error = CookieRedirectException(hostname = "example.com", message = expectedMessage)
.toBitwardenError()
val result = error.parseErrorBodyOrNull<CreateCipherResponseJson.Invalid>(