stripe-terminal-android
stripe-terminal-android copied to clipboard
IOException -> HandoffRpcCallbackListener message="Handoff client received Legacy callback"
Summary
When I'm running my android app, I'm constantly and randomly receiving the errors in the title.
This is the stacktrace:
2024-08-01 11:36:13.072 8404-8470 StripeTerminal I class=TerminalStatusManager message="reportCardStatusChange CARD_REMOVED."
2024-08-01 11:36:13.073 8404-8470 StripeTerminal I class=ProxyReaderListener message=onReportReaderEvent(CARD_REMOVED)
2024-08-01 11:36:13.074 8404-8477 StripeTerminal D class=AidlRpcClient message=makeRequest service=HANDOFF_SERVICE method=ACTIVATE_TERMINAL requestId=1
2024-08-01 11:36:13.074 8404-8427 StripeTerminal E class=HandoffRpcCallbackListener message="Handoff client received Legacy callback"
java.io.IOException: Empty request body
at com.stripe.stripeterminal.handoffclient.HandoffRpcCallbackListener.onUpdate(HandoffRpcCallbackListener.kt:45)
at com.stripe.core.aidlrpc.AidlRpcUpdateListener$Stub.onTransact(AidlRpcUpdateListener.java:74)
at android.os.Binder.execTransactInternal(Binder.java:1021)
at android.os.Binder.execTransact(Binder.java:994)
2024-08-01 11:36:13.080 8404-8470 StripeTerminal W class=HandoffRpcCallbackListener message="encountered unknown card status" cardStatus=null onReaderUpdate="OnReaderUpdate{offline_status_details_changed=OnOfflineStatusDetailsChanged{offline_stats=OfflineStats{payments_count=0, setup_intents_count=0}, network_status=ONLINE}}"
2024-08-01 11:36:13.082 8404-8423 StripeTerminal E class=HandoffRpcCallbackListener message="Handoff client received Legacy callback"
java.io.IOException: Empty request body
at com.stripe.stripeterminal.handoffclient.HandoffRpcCallbackListener.onUpdate(HandoffRpcCallbackListener.kt:45)
at com.stripe.core.aidlrpc.AidlRpcUpdateListener$Stub.onTransact(AidlRpcUpdateListener.java:74)
at android.os.Binder.execTransactInternal(Binder.java:1021)
at android.os.Binder.execTransact(Binder.java:994)
2024-08-01 11:36:13.088 8404-8427 StripeTerminal E class=HandoffRpcCallbackListener message="Handoff client received Legacy callback"
java.io.IOException: Empty request body
at com.stripe.stripeterminal.handoffclient.HandoffRpcCallbackListener.onUpdate(HandoffRpcCallbackListener.kt:45)
at com.stripe.core.aidlrpc.AidlRpcUpdateListener$Stub.onTransact(AidlRpcUpdateListener.java:74)
at android.os.Binder.execTransactInternal(Binder.java:1021)
at android.os.Binder.execTransact(Binder.java:994)
Code to reproduce
private val discoveryListener: DiscoveryListener = object : DiscoveryListener {
override fun onUpdateDiscoveredReaders(readers: List<Reader>) {
Log.i(TAG, "onUpdateDiscoveredReaders we have ${readers.size} readers")
val deviceSerialNumber = Build.getSerial()
val reader = readers.firstOrNull { it.networkStatus == Reader.NetworkStatus.ONLINE && it.serialNumber == deviceSerialNumber}
if (reader != null) {
Log.i(TAG, "We have a valid reader, so let's proceed")
targetReader = reader
targetReader.id?.let { id ->
Log.i(TAG, "We are saving the terminal model with id $id")
_localStorage.saveTerminalModel(TerminalModel(id))
Log.i(TAG, "Let's try to get the location")
getLocation(id)
}
Log.i(TAG, "Let's try to connect to the reader")
connectReader()
} else {
Log.i(TAG, "No reader could be found")
_userMessage.update {
"Unable to connect to the reader"
}
_settingStatus.update { SettingWorkFlow.GET_ERROR }
}
}
}
private val discoveryCallback: Callback = object : Callback {
override fun onSuccess() {
Log.d(TAG, "discoveryCallback onSuccess")
}
override fun onFailure(e: TerminalException) {
Log.e(TAG, "discoveryCallback onFailure", e)
_userMessage.update { TerminalExceptionWrapper(e).errorMessage }
_settingStatus.update { SettingWorkFlow.GET_ERROR }
}
}
fun discoveryReaders() {
Log.i(TAG, "start discovery reader")
discoveryTask = Terminal.getInstance().discoverReaders(
config,
discoveryListener,
discoveryCallback
)
}
fun connectReader() {
Log.i(TAG, "connect reader...")
getCurrentReader()?.let { reader ->
// same one , skip
if (targetReader.id == reader.id) {
Log.i(TAG, "Find reader")
return
}
// different reader , disconnect old first then connect new one again
val currentReader: Reader = reader
Terminal.getInstance().disconnectReader(object : Callback {
override fun onSuccess() {
Log.d(TAG, "Current Reader [ ${currentReader.id} ] disconnect success ")
}
override fun onFailure(e: TerminalException) {
Log.e(TAG, "Current Reader [ ${currentReader.id} ] disconnect fail ")
}
})
}
Log.i(TAG, "Connecting to new Reader [ ${targetReader.id} ] .... ")
val readerCallback: ReaderCallback = object : ReaderCallback {
override fun onSuccess(reader: Reader) {
Log.i(TAG, "Reader [ ${targetReader.id} ] Connected ")
}
override fun onFailure(e: TerminalException) {
Log.i(TAG, "readerCallback onFailure", e)
_userMessage.update { TerminalExceptionWrapper(e, _context).errorMessage }
}
}
val readerListener = object : HandoffReaderListener {
override fun onReportReaderEvent(event: ReaderEvent) {
super.onReportReaderEvent(event)
Log.d(TAG, "onReportReaderEvent: $event")
}
}
Terminal.getInstance().connectHandoffReader(
targetReader,
ConnectionConfiguration.HandoffConnectionConfiguration(),
readerListener,
readerCallback
)
}
Android version
Android 10, API 29
Impacted devices (Android devices or readers)
I'm testing in a S700 terminal reader
SDK version
I've tried several, including the latest 3.8.0
Any update on this issue I am also facing same issue. what could be the solution for this
Adding a 👍 as I am seeing the same on our S700 project.
From what I can tell 4.3.0 does not fix this, here's my dependency configuration:
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0")
implementation("androidx.fragment:fragment-ktx:1.8.5")
implementation("androidx.compose.ui:ui:1.7.6")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
implementation("com.stripe:stripeterminal-core:4.3.0")
implementation("com.stripe:stripeterminal-handoffclient:4.3.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.0")
implementation("jakarta.validation:jakarta.validation-api:3.0.0")
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
Hi folks 👋 ,
Thank you all for reporting this issue and providing the detailed logs. We're aware of these Handoff client received Legacy callback log messages and plan to address them in a future release to reduce the noise in your logs.
I want to clarify that based on our investigation, these messages are actually non-critical and shouldn't affect the functionality of your integration.
Can you all confirm that this is primarily a logging issue? Have you noticed any actual functionality problems with your terminal operations (payments, connection stability, etc.) that coincide with these errors? If there are functional issues you're experiencing, could you please share those details so we can investigate further?
For the short term, you can filter these messages out in your logging infrastructure or debug views since they don't indicate a problem that requires immediate action.
We'll update this thread once we have a fix available in an upcoming SDK release.
Thanks for your patience!
Closing as we've downgraded the log level to info ^1