Skip to content

Commit 0e821b5

Browse files
committed
parse all error messages
1 parent 4a2c909 commit 0e821b5

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

platforms/android/lib/src/main/java/com/shopify/checkoutkit/CheckoutProtocol.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,14 @@ public object CheckoutProtocol {
6767
public val lineItemsChange: NotificationDescriptor<Checkout> = checkoutDescriptor("ec.line_items.change")
6868
internal val buyerChange: NotificationDescriptor<Checkout> = checkoutDescriptor("ec.buyer.change")
6969
public val totalsChange: NotificationDescriptor<Checkout> = checkoutDescriptor("ec.totals.change")
70-
public val error: NotificationDescriptor<CheckoutError> = NotificationDescriptor(
70+
public val error: NotificationDescriptor<ErrorResponse> = NotificationDescriptor(
7171
method = "ec.error",
7272
decode = { params ->
73-
params?.jsonObject?.get("messages")?.let {
73+
params?.jsonObject?.get("error")?.let {
7474
try {
75-
json.decodeFromJsonElement<List<CheckoutError>>(it).firstOrNull()
75+
json.decodeFromJsonElement<ErrorResponse>(it)
7676
} catch (e: Exception) {
77-
log.d(BaseWebView.ECP_LOG_TAG, "Failed to decode ec.error messages: $e raw=$it")
77+
log.d(BaseWebView.ECP_LOG_TAG, "Failed to decode ec.error params: $e raw=$it")
7878
null
7979
}
8080
}
@@ -320,7 +320,7 @@ internal sealed class WindowOpenResult {
320320
data class Rejected(val reason: String? = null) : WindowOpenResult()
321321
}
322322

323-
/** Payload delivered with the [CheckoutProtocol.error] notification. */
323+
/** Legacy single-message error payload retained for source compatibility. */
324324
@Serializable
325325
public data class CheckoutError internal constructor(
326326
public val code: String? = null,

platforms/android/lib/src/test/java/com/shopify/checkoutkit/CheckoutProtocolTest.kt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,28 @@ class CheckoutProtocolTest {
135135

136136
@Test
137137
fun `process dispatches ec error to registered handler with decoded payload`() {
138-
var received: CheckoutError? = null
138+
var received: ErrorResponse? = null
139139
val client = CheckoutProtocol.Client()
140140
.on(CheckoutProtocol.error) { received = it }
141141

142142
val errorMsg = """{"jsonrpc":"2.0","method":"ec.error","params":""" +
143-
"""{"messages":[{"code":"unknown_error","content":"fail","severity":"unrecoverable"}]}}"""
143+
"""{"error":{"ucp":{"version":"2026-04-08","status":"error"},"messages":[""" +
144+
"""{"type":"error","code":"unknown_error","content":"fail","severity":"unrecoverable"},""" +
145+
"""{"type":"error","code":"session_expired","content":"expired","severity":"recoverable"}""" +
146+
"""],"continue_url":"https://example.com/retry"}}}"""
144147
client.process(errorMsg)
145148
shadowOf(Looper.getMainLooper()).runToEndOfTasks()
146149

147-
assertThat(received?.code).isEqualTo("unknown_error")
148-
assertThat(received?.content).isEqualTo("fail")
149-
assertThat(received?.severity).isEqualTo("unrecoverable")
150+
assertThat(received?.ucp?.version).isEqualTo("2026-04-08")
151+
assertThat(received?.ucp?.status).isEqualTo(StatusEnum.Error)
152+
assertThat(received?.messages).hasSize(2)
153+
assertThat(received?.messages?.get(0)?.type).isEqualTo(MessageType.Error)
154+
assertThat(received?.messages?.get(0)?.code).isEqualTo("unknown_error")
155+
assertThat(received?.messages?.get(0)?.content).isEqualTo("fail")
156+
assertThat(received?.messages?.get(0)?.severity).isEqualTo(Severity.Unrecoverable)
157+
assertThat(received?.messages?.get(1)?.code).isEqualTo("session_expired")
158+
assertThat(received?.messages?.get(1)?.severity).isEqualTo(Severity.Recoverable)
159+
assertThat(received?.continueURL).isEqualTo("https://example.com/retry")
150160
}
151161

152162
@Test

0 commit comments

Comments
 (0)