JuulLabs / kable

Kotlin Asynchronous Bluetooth Low-Energy
https://juullabs.github.io/kable
Apache License 2.0
843 stars 83 forks source link

NullPointerException when getting an Android peripheral from an advertisement #332

Open rsicarelli opened 2 years ago

rsicarelli commented 2 years ago

After successfully scan and find an advertisement, trying to get the peripheral throws a NullPointerException:

val peripheral = Scanner()
    .advertisements
    .map { advertisement ->
        //Line below throws NullPointer
        scope.peripheral(advertisement)
    }
    .first()

Stacktrace:

2022-05-27 10:10:03.018 E/ java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter <this>
        at com.juul.kable.BluetoothDeviceKt.close(Unknown Source:2)
        at com.juul.kable.AndroidPeripheral$job$1$1.invoke(Peripheral.kt:148)
        at com.juul.kable.AndroidPeripheral$job$1$1.invoke(Peripheral.kt:145)
        at kotlinx.coroutines.JobSupport.invokeOnCompletion(JobSupport.kt:1548)
        at kotlinx.coroutines.JobSupport.invokeOnCompletion(JobSupport.kt:449)
        at com.juul.kable.AndroidPeripheral.<init>(Peripheral.kt:145)
        at com.juul.kable.PeripheralKt.peripheral(Peripheral.kt:99)
        at com.juul.kable.PeripheralKt.peripheral(Peripheral.kt:91)
        at kotlinx.coroutines.flow.FlowKt__TransformKt$onEach$$inlined$unsafeTransform$1$2.emit(Emitters.kt:224)
        at kotlinx.coroutines.flow.FlowKt__ErrorsKt$catchImpl$2.emit(Errors.kt:158)
        at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:62)
        at kotlinx.coroutines.flow.FlowKt__ChannelsKt.access$emitAllImpl$FlowKt__ChannelsKt(Channels.kt:1)
        at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:14)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)

Configuration:

Name: OnePlus 6 Version: 11

Name: Xiaomi Readmi9T Version: 11

Kable version: 0.17.1


More details

twyatt commented 2 years ago

Thanks for reporting. Will try to investigate this soon.

twyatt commented 2 years ago

It shouldn't fail with the NullPointerException, so I will look into that, but the stacktrace eludes to the fact that maybe your scope is cancelling in the middle of the scan process?

rsicarelli commented 2 years ago

It shouldn't fail with the NullPointerException, so I will look into that, but the stacktrace eludes to the fact that maybe your scope is cancelling in the middle of the scan process?

Yeah you might be correct. I had two different scopes for scanning and connection. After unifying them, the crash is gone.

Not sure if this issue is still relevant, feel free to close if you wish 👍

twyatt commented 2 years ago

Not sure if this issue is still relevant, feel free to close if wish 👍

I'll close out after I look into if there is a way Kable could throw a more informative failure in the situation you hit. Thanks for reporting, and following up with how you resolved the issue. 👍