diff --git a/common/src/main/java/com/ably/tracking/common/Ably.kt b/common/src/main/java/com/ably/tracking/common/Ably.kt index b8263a655..824194b4d 100644 --- a/common/src/main/java/com/ably/tracking/common/Ably.kt +++ b/common/src/main/java/com/ably/tracking/common/Ably.kt @@ -4,6 +4,7 @@ import com.ably.tracking.ConnectionException import com.ably.tracking.EnhancedLocationUpdate import com.ably.tracking.ErrorInformation import com.ably.tracking.LocationUpdate +import com.ably.tracking.common.logging.createLoggingTag import com.ably.tracking.common.logging.d import com.ably.tracking.common.logging.e import com.ably.tracking.common.logging.i @@ -253,6 +254,7 @@ constructor( private val gson = Gson() private val ably: AblyRealtime private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) + private val TAG = createLoggingTag(this) init { try { @@ -266,7 +268,9 @@ constructor( } ably = AblyRealtime(clientOptions) } catch (exception: AblyException) { - throw exception.errorInfo.toTrackingException() + throw exception.errorInfo.toTrackingException().also { + logHandler?.w("$TAG Failed to create an Ably instance", it) + } } } @@ -309,11 +313,13 @@ constructor( val renewAuthResult = renewAuthSuspending() renewAuthResult.errorInfo?.let { + logHandler?.w("$TAG Failed to renew auth while entering the presence of channel ${channel.name}", it.toTrackingException()) throw it.toTrackingException() } channel.attachSuspending() channel.enterPresenceSuspending(presenceData) } else { + logHandler?.w("$TAG Failed to enter the presence of channel ${channel.name}", connectionException) throw connectionException } } @@ -328,6 +334,7 @@ constructor( continuation.resume(RenewAuthResult(success, tokenDetails, errorInfo)) } } catch (e: Exception) { + logHandler?.w("$TAG Failed to renew Ably auth", e) e.printStackTrace() continuation.resumeWithException(e) } @@ -355,12 +362,15 @@ constructor( enterChannelPresence(channel, presenceData) callback(Result.success(Unit)) } catch (connectionException: ConnectionException) { + logHandler?.w("$TAG Failed to connect for channel ${channel.name}", connectionException) ably.channels.release(channelName) callback(Result.failure(connectionException)) } } } catch (ablyException: AblyException) { - callback(Result.failure(ablyException.errorInfo.toTrackingException())) + val trackingException = ablyException.errorInfo.toTrackingException() + logHandler?.w("$TAG Failed to connect for trackable $trackableId", trackingException) + callback(Result.failure(trackingException)) } } else { callback(Result.success(Unit)) @@ -396,6 +406,7 @@ constructor( result.getOrThrow() continuation.resume(Result.success(Unit)) } catch (exception: ConnectionException) { + logHandler?.w("$TAG Failed to connect for trackable $trackableId", exception) continuation.resume(Result.failure(exception)) } } @@ -410,6 +421,7 @@ constructor( disconnectChannel(channelToRemove, presenceData) callback(Result.success(Unit)) } catch (exception: ConnectionException) { + logHandler?.w("$TAG Failed to disconnect for trackable $trackableId", exception) callback(Result.failure(exception)) } } else { @@ -454,15 +466,17 @@ constructor( } override fun onError(reason: ErrorInfo?) { - continuation.resumeWithException( - reason?.toTrackingException() - ?: ConnectionException(ErrorInformation("Unknown error when leaving presence ${channel.name}")) - ) + val trackingException = reason?.toTrackingException() + ?: ConnectionException(ErrorInformation("Unknown error when leaving presence ${channel.name}")) + logHandler?.w("$TAG Failed to leave presence for channel ${channel.name}", trackingException) + continuation.resumeWithException(trackingException) } } ) } catch (ablyException: AblyException) { - continuation.resumeWithException(ablyException.errorInfo.toTrackingException()) + val trackingException = ablyException.errorInfo.toTrackingException() + logHandler?.w("$TAG Failed to leave presence for channel ${channel.name}", trackingException) + continuation.resumeWithException(trackingException) } } } @@ -477,6 +491,7 @@ constructor( it.getOrThrow() continuation.resume(Result.success(Unit)) } catch (exception: ConnectionException) { + logHandler?.w("$TAG Failed to disconnect for trackable $trackableId", exception) continuation.resume(Result.failure(exception)) } } @@ -491,7 +506,7 @@ constructor( val trackableChannel = getChannelIfExists(trackableId) if (trackableChannel != null) { val locationUpdateJson = locationUpdate.toMessageJson(gson) - logHandler?.d("sendEnhancedLocationMessage: publishing: $locationUpdateJson") + logHandler?.d("$TAG sendEnhancedLocationMessage: publishing: $locationUpdateJson") sendMessage( trackableChannel, Message(EventNames.ENHANCED, locationUpdateJson).apply { @@ -512,7 +527,7 @@ constructor( val trackableChannel = getChannelIfExists(trackableId) if (trackableChannel != null) { val locationUpdateJson = locationUpdate.toMessageJson(gson) - logHandler?.d("sendRawLocationMessage: publishing: $locationUpdateJson") + logHandler?.d("$TAG sendRawLocationMessage: publishing: $locationUpdateJson") sendMessage( trackableChannel, Message(EventNames.RAW, locationUpdateJson).apply { @@ -533,6 +548,7 @@ constructor( } callback(Result.success(Unit)) } catch (exception: ConnectionException) { + logHandler?.w("$TAG Failed to send message for channel ${channel.name}", exception) callback(Result.failure(exception)) } } @@ -549,15 +565,17 @@ constructor( } override fun onError(reason: ErrorInfo?) { - continuation.resumeWithException( - reason?.toTrackingException() - ?: ConnectionException(ErrorInformation("Unknown error when sending message ${channel.name}")) - ) + val trackingException = reason?.toTrackingException() + ?: ConnectionException(ErrorInformation("Unknown error when sending message ${channel.name}")) + logHandler?.w("$TAG Failed to suspend send message for channel ${channel.name}", trackingException) + continuation.resumeWithException(trackingException) } } ) } catch (exception: AblyException) { - continuation.resumeWithException(exception.errorInfo.toTrackingException()) + val trackingException = exception.errorInfo.toTrackingException() + logHandler?.w("$TAG Failed to suspend send message for channel ${channel.name}", trackingException) + continuation.resumeWithException(trackingException) } } } @@ -579,7 +597,9 @@ constructor( ) } } catch (exception: AblyException) { - throw exception.errorInfo.toTrackingException() + throw exception.errorInfo.toTrackingException().also { + logHandler?.w("$TAG Failed to subscriber for enhanced events for channel ${channel.name}", it) + } } } } @@ -601,7 +621,9 @@ constructor( ) } } catch (exception: AblyException) { - throw exception.errorInfo.toTrackingException() + throw exception.errorInfo.toTrackingException().also { + logHandler?.w("$TAG Failed to subscriber for raw events for channel ${channel.name}", it) + } } } } @@ -627,7 +649,7 @@ constructor( private fun createMalformedLocationUpdateLogMessage(isRawLocation: Boolean): String { val locationType = if (isRawLocation) "raw" else "enhanced" - return "Could not deserialize $locationType location update message, channel will be closed" + return "$TAG Could not deserialize $locationType location update message, channel will be closed" } override fun subscribeForPresenceMessages( @@ -656,12 +678,13 @@ constructor( if (parsedMessage != null) { listener(parsedMessage) } else { - logHandler?.w("Presence message in unexpected format: $it") + logHandler?.w("$TAG Presence message in unexpected format: $it") } } Result.success(Unit) } catch (exception: AblyException) { val trackingException = exception.errorInfo.toTrackingException() + logHandler?.w("$TAG Failed to subscriber for presence messages for trackable $trackableId", trackingException) Result.failure(trackingException) } } @@ -680,7 +703,9 @@ constructor( val currentPresenceMessages = getAllCurrentMessagesFromPresence(channel) continuation.resume(Result.success(currentPresenceMessages)) } catch (ablyException: AblyException) { - continuation.resume(Result.failure(ablyException.errorInfo.toTrackingException())) + val trackingException = ablyException.errorInfo.toTrackingException() + logHandler?.w("$TAG Failed to get current presence messages for trackable $trackableId", trackingException) + continuation.resume(Result.failure(trackingException)) } } } @@ -692,7 +717,7 @@ constructor( channel.presence.get(true).mapNotNull { presenceMessage -> presenceMessage.toTracking(gson).also { if (it == null) { - logHandler?.w("Presence message in unexpected format: $presenceMessage") + logHandler?.w("$TAG Presence message in unexpected format: $presenceMessage") } } } @@ -712,6 +737,7 @@ constructor( } Result.success(Unit) } catch (exception: ConnectionException) { + logHandler?.w("$TAG Failed to update presence data for trackable $trackableId", exception) Result.failure(exception) } } @@ -727,15 +753,17 @@ constructor( } override fun onError(reason: ErrorInfo?) { - continuation.resumeWithException( - reason?.toTrackingException() - ?: ConnectionException(ErrorInformation("Unknown error when updating presence ${channel.name}")) - ) + val trackingException = reason?.toTrackingException() + ?: ConnectionException(ErrorInformation("Unknown error when updating presence ${channel.name}")) + logHandler?.w("$TAG Failed to suspend update presence data for channel ${channel.name}", trackingException) + continuation.resumeWithException(trackingException) } } ) } catch (exception: AblyException) { - continuation.resumeWithException(exception.errorInfo.toTrackingException()) + val trackingException = exception.errorInfo.toTrackingException() + logHandler?.w("$TAG Failed to suspend update presence data for channel ${channel.name}", trackingException) + continuation.resumeWithException(trackingException) } } } @@ -801,14 +829,14 @@ constructor( ) { try { if (channel.state == ChannelState.suspended) { - logHandler?.w("Trying to perform an operation on a suspended channel ${channel.name}, waiting for the channel to be reconnected") + logHandler?.w("$TAG Trying to perform an operation on a suspended channel ${channel.name}, waiting for the channel to be reconnected") waitForChannelReconnection(channel) } operation(channel) } catch (exception: ConnectionException) { if (exception.isConnectionResumeException()) { logHandler?.w( - "Connection resume failed for channel ${channel.name}, waiting for the channel to be reconnected", + "$TAG Connection resume failed for channel ${channel.name}, waiting for the channel to be reconnected", exception ) try { @@ -816,7 +844,7 @@ constructor( operation(channel) } catch (secondException: ConnectionException) { logHandler?.w( - "Retrying the operation on channel ${channel.name} has failed for the second time", + "$TAG Retrying the operation on channel ${channel.name} has failed for the second time", secondException ) throw secondException @@ -850,7 +878,9 @@ constructor( } } } catch (exception: TimeoutCancellationException) { - throw ConnectionException(ErrorInformation("Timeout was thrown when waiting for channel to attach")) + throw ConnectionException(ErrorInformation("Timeout was thrown when waiting for channel to attach")).also { + logHandler?.w("$TAG Timeout while waiting for channel reconnection ${channel.name}", it) + } } } @@ -880,15 +910,17 @@ constructor( } override fun onError(reason: ErrorInfo?) { - continuation.resumeWithException( - reason?.toTrackingException() - ?: ConnectionException(ErrorInformation("Unknown error when entering presence $name")) - ) + val trackingException = reason?.toTrackingException() + ?: ConnectionException(ErrorInformation("Unknown error when entering presence $name")) + logHandler?.w("$TAG Failed to suspend enter presence for channel $name", trackingException) + continuation.resumeWithException(trackingException) } } ) } catch (ablyException: AblyException) { - continuation.resumeWithException(ablyException.errorInfo.toTrackingException()) + val trackingException = ablyException.errorInfo.toTrackingException() + logHandler?.w("$TAG Failed to suspend enter presence for channel $name", trackingException) + continuation.resumeWithException(trackingException) } } } @@ -906,14 +938,16 @@ constructor( } override fun onError(reason: ErrorInfo?) { - continuation.resumeWithException( - reason?.toTrackingException() - ?: ConnectionException(ErrorInformation("Unknown error when attaching channel $name")) - ) + val trackingException = reason?.toTrackingException() + ?: ConnectionException(ErrorInformation("Unknown error when attaching channel $name")) + logHandler?.w("$TAG Failed to suspend attach to channel $name", trackingException) + continuation.resumeWithException(trackingException) } }) } catch (ablyException: AblyException) { - continuation.resumeWithException(ablyException.errorInfo.toTrackingException()) + val trackingException = ablyException.errorInfo.toTrackingException() + logHandler?.w("$TAG Failed to suspend attach to channel $name", trackingException) + continuation.resumeWithException(trackingException) } } } @@ -928,6 +962,7 @@ constructor( ably.connectSuspending() Result.success(Unit) } catch (connectionException: ConnectionException) { + logHandler?.w("$TAG Failed to start Ably connection", connectionException) Result.failure(connectionException) } } @@ -937,6 +972,7 @@ constructor( ably.closeSuspending() Result.success(Unit) } catch (connectionException: ConnectionException) { + logHandler?.w("$TAG Failed to stop Ably connection", connectionException) Result.failure(connectionException) } } @@ -977,7 +1013,9 @@ constructor( } } } catch (exception: TimeoutCancellationException) { - throw ConnectionException(ErrorInformation("Timeout was thrown when waiting for Ably to connect")) + throw ConnectionException(ErrorInformation("Timeout was thrown when waiting for Ably to connect")).also { + logHandler?.w("$TAG Timeout while waiting for Ably to connect", it) + } } } diff --git a/common/src/main/java/com/ably/tracking/common/CallbackFunctionModels.kt b/common/src/main/java/com/ably/tracking/common/CallbackFunctionModels.kt index cb145505a..b6695bc42 100644 --- a/common/src/main/java/com/ably/tracking/common/CallbackFunctionModels.kt +++ b/common/src/main/java/com/ably/tracking/common/CallbackFunctionModels.kt @@ -20,11 +20,17 @@ typealias ResultCallbackFunction = CallbackFunction> * Utility function adapts [Continuation] to fit in [ResultCallbackFunction] signature. Callback result is unpacked and * used to resume the continuation. */ -fun Continuation.wrapInResultCallback(): ResultCallbackFunction = +fun Continuation.wrapInResultCallback( + onSuccess: () -> Unit = {}, + onError: (Exception) -> Unit = {}, +): ResultCallbackFunction = { result -> try { - resume(result.getOrThrow()) + val resultValue = result.getOrThrow() + onSuccess() + resume(resultValue) } catch (exception: Exception) { + onError(exception) resumeWithException(exception) } } diff --git a/publishing-sdk/src/main/java/com/ably/tracking/publisher/DefaultPublisher.kt b/publishing-sdk/src/main/java/com/ably/tracking/publisher/DefaultPublisher.kt index e7534d58c..e1deed650 100644 --- a/publishing-sdk/src/main/java/com/ably/tracking/publisher/DefaultPublisher.kt +++ b/publishing-sdk/src/main/java/com/ably/tracking/publisher/DefaultPublisher.kt @@ -8,6 +8,9 @@ import com.ably.tracking.LocationUpdate import com.ably.tracking.Resolution import com.ably.tracking.TrackableState import com.ably.tracking.common.Ably +import com.ably.tracking.common.logging.createLoggingTag +import com.ably.tracking.common.logging.v +import com.ably.tracking.common.logging.w import com.ably.tracking.common.wrapInResultCallback import com.ably.tracking.logging.LogHandler import kotlin.coroutines.suspendCoroutine @@ -22,13 +25,14 @@ constructor( mapbox: Mapbox, resolutionPolicyFactory: ResolutionPolicy.Factory, routingProfile: RoutingProfile, - logHandler: LogHandler?, + private val logHandler: LogHandler?, areRawLocationsEnabled: Boolean?, sendResolutionEnabled: Boolean, constantLocationEngineResolution: Resolution?, ) : Publisher { private val core: CorePublisher + private val TAG = createLoggingTag(this) override val active: Trackable? get() = core.active @@ -53,29 +57,58 @@ constructor( sendResolutionEnabled, constantLocationEngineResolution, ) + logHandler?.v("$TAG Created a publisher instance") } override suspend fun track(trackable: Trackable): StateFlow { + logHandler?.v("$TAG Publisher track operation started") return suspendCoroutine { continuation -> - core.trackTrackable(trackable, continuation.wrapInResultCallback()) + core.trackTrackable( + trackable, + continuation.wrapInResultCallback( + onSuccess = { logHandler?.v("$TAG Publisher track operation succeeded") }, + onError = { logHandler?.w("$TAG Publisher track operation failed", it) }, + ), + ) } } override suspend fun add(trackable: Trackable): StateFlow { + logHandler?.v("$TAG Publisher add operation started") return suspendCoroutine { continuation -> - core.addTrackable(trackable, continuation.wrapInResultCallback()) + core.addTrackable( + trackable, + continuation.wrapInResultCallback( + onSuccess = { logHandler?.v("$TAG Publisher add operation succeeded") }, + onError = { logHandler?.w("$TAG Publisher add operation failed", it) }, + ), + ) } } override suspend fun remove(trackable: Trackable): Boolean { + logHandler?.v("$TAG Publisher remove operation started") return suspendCoroutine { continuation -> - core.removeTrackable(trackable, continuation.wrapInResultCallback()) + core.removeTrackable( + trackable, + continuation.wrapInResultCallback( + onSuccess = { logHandler?.v("$TAG Publisher remove operation succeeded") }, + onError = { logHandler?.w("$TAG Publisher remove operation failed", it) }, + ), + ) } } override suspend fun stop(timeoutInMilliseconds: Long) { + logHandler?.v("$TAG Publisher stop operation started") suspendCoroutine { continuation -> - core.stop(timeoutInMilliseconds, continuation.wrapInResultCallback()) + core.stop( + timeoutInMilliseconds, + continuation.wrapInResultCallback( + onSuccess = { logHandler?.v("$TAG Publisher stop operation succeeded") }, + onError = { logHandler?.w("$TAG Publisher stop operation failed", it) }, + ), + ) } } diff --git a/publishing-sdk/src/main/java/com/ably/tracking/publisher/PublisherBuilder.kt b/publishing-sdk/src/main/java/com/ably/tracking/publisher/PublisherBuilder.kt index 29c3141eb..3624c73d8 100644 --- a/publishing-sdk/src/main/java/com/ably/tracking/publisher/PublisherBuilder.kt +++ b/publishing-sdk/src/main/java/com/ably/tracking/publisher/PublisherBuilder.kt @@ -7,6 +7,8 @@ import androidx.annotation.RequiresPermission import com.ably.tracking.BuilderConfigurationIncompleteException import com.ably.tracking.Resolution import com.ably.tracking.common.DefaultAbly +import com.ably.tracking.common.logging.createLoggingTag +import com.ably.tracking.common.logging.v import com.ably.tracking.connection.ConnectionConfiguration import com.ably.tracking.logging.LogHandler @@ -26,6 +28,7 @@ internal data class PublisherBuilder( val constantLocationEngineResolution: Resolution? = null, val vehicleProfile: VehicleProfile = VehicleProfile.CAR, ) : Publisher.Builder { + private val TAG = createLoggingTag(this) override fun connection(configuration: ConnectionConfiguration): Publisher.Builder = this.copy(connectionConfiguration = configuration) @@ -72,8 +75,10 @@ internal data class PublisherBuilder( @RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION]) override fun start(): Publisher { if (isMissingRequiredFields()) { + logHandler?.v("$TAG Creating a publisher instance failed due to missing required fields") throw BuilderConfigurationIncompleteException() } + logHandler?.v("$TAG Creating a publisher instance") // All below fields are required and above code checks if they are nulls, so using !! should be safe from NPE return DefaultPublisher( DefaultAbly(connectionConfiguration!!, logHandler), diff --git a/subscribing-sdk/src/main/java/com/ably/tracking/subscriber/DefaultSubscriber.kt b/subscribing-sdk/src/main/java/com/ably/tracking/subscriber/DefaultSubscriber.kt index c305f72a7..ab87f5d08 100644 --- a/subscribing-sdk/src/main/java/com/ably/tracking/subscriber/DefaultSubscriber.kt +++ b/subscribing-sdk/src/main/java/com/ably/tracking/subscriber/DefaultSubscriber.kt @@ -5,7 +5,11 @@ import com.ably.tracking.Resolution import com.ably.tracking.TrackableState import com.ably.tracking.annotations.Experimental import com.ably.tracking.common.Ably +import com.ably.tracking.common.logging.createLoggingTag +import com.ably.tracking.common.logging.v +import com.ably.tracking.common.logging.w import com.ably.tracking.common.wrapInResultCallback +import com.ably.tracking.logging.LogHandler import com.ably.tracking.subscriber.workerqueue.WorkerSpecification import kotlin.coroutines.suspendCoroutine import kotlinx.coroutines.flow.SharedFlow @@ -15,8 +19,10 @@ internal class DefaultSubscriber( ably: Ably, resolution: Resolution?, trackableId: String, + private val logHandler: LogHandler?, ) : Subscriber { private val core: CoreSubscriber + private val TAG = createLoggingTag(this) override val locations: SharedFlow get() = core.enhancedLocations @@ -39,33 +45,53 @@ internal class DefaultSubscriber( init { core = createCoreSubscriber(ably, resolution, trackableId) + logHandler?.v("$TAG Created a subscriber instance") } /** * This method must be run before running any other method from [DefaultSubscriber]. */ suspend fun start() { + logHandler?.v("$TAG Subscriber start operation started") suspendCoroutine { continuation -> core.enqueue( - WorkerSpecification.StartConnection(continuation.wrapInResultCallback()) + WorkerSpecification.StartConnection( + continuation.wrapInResultCallback( + onSuccess = { logHandler?.v("$TAG Subscriber start operation succeeded") }, + onError = { logHandler?.w("$TAG Subscriber start operation failed", it) }, + ) + ) ) } } override suspend fun resolutionPreference(resolution: Resolution?) { + logHandler?.v("$TAG Subscriber resolutionPreference operation started") // send change request over channel and wait for the result suspendCoroutine { continuation -> core.enqueue( - WorkerSpecification.ChangeResolution(resolution, continuation.wrapInResultCallback()) + WorkerSpecification.ChangeResolution( + resolution, + continuation.wrapInResultCallback( + onSuccess = { logHandler?.v("$TAG Subscriber resolutionPreference operation succeeded") }, + onError = { logHandler?.w("$TAG Subscriber resolutionPreference operation failed", it) }, + ), + ) ) } } override suspend fun stop() { + logHandler?.v("$TAG Subscriber stop operation started") // send stop request over channel and wait for the result suspendCoroutine { continuation -> core.enqueue( - WorkerSpecification.StopConnection(continuation.wrapInResultCallback()) + WorkerSpecification.StopConnection( + continuation.wrapInResultCallback( + onSuccess = { logHandler?.v("$TAG Subscriber stop operation succeeded") }, + onError = { logHandler?.w("$TAG Subscriber stop operation failed", it) }, + ) + ) ) } } diff --git a/subscribing-sdk/src/main/java/com/ably/tracking/subscriber/SubscriberBuilder.kt b/subscribing-sdk/src/main/java/com/ably/tracking/subscriber/SubscriberBuilder.kt index cc0969c95..159a73e28 100644 --- a/subscribing-sdk/src/main/java/com/ably/tracking/subscriber/SubscriberBuilder.kt +++ b/subscribing-sdk/src/main/java/com/ably/tracking/subscriber/SubscriberBuilder.kt @@ -3,6 +3,8 @@ package com.ably.tracking.subscriber import com.ably.tracking.BuilderConfigurationIncompleteException import com.ably.tracking.Resolution import com.ably.tracking.common.DefaultAbly +import com.ably.tracking.common.logging.createLoggingTag +import com.ably.tracking.common.logging.v import com.ably.tracking.connection.ConnectionConfiguration import com.ably.tracking.logging.LogHandler @@ -12,6 +14,7 @@ internal data class SubscriberBuilder( val logHandler: LogHandler? = null, val trackingId: String? = null, ) : Subscriber.Builder { + private val TAG = createLoggingTag(this) override fun connection(configuration: ConnectionConfiguration): Subscriber.Builder = this.copy(connectionConfiguration = configuration) @@ -27,13 +30,16 @@ internal data class SubscriberBuilder( override suspend fun start(): Subscriber { if (isMissingRequiredFields()) { + logHandler?.v("$TAG Creating a subscriber instance failed due to missing required fields") throw BuilderConfigurationIncompleteException() } + logHandler?.v("$TAG Creating a subscriber instance") // All below fields are required and above code checks if they are nulls, so using !! should be safe from NPE return DefaultSubscriber( DefaultAbly(connectionConfiguration!!, logHandler), resolution, trackingId!!, + logHandler, ).apply { start() } diff --git a/subscribing-sdk/src/test/java/com/ably/tracking/subscriber/DefaultSubscriberTest.kt b/subscribing-sdk/src/test/java/com/ably/tracking/subscriber/DefaultSubscriberTest.kt index e1d9d2f66..e2b276245 100644 --- a/subscribing-sdk/src/test/java/com/ably/tracking/subscriber/DefaultSubscriberTest.kt +++ b/subscribing-sdk/src/test/java/com/ably/tracking/subscriber/DefaultSubscriberTest.kt @@ -15,7 +15,7 @@ import java.util.UUID class DefaultSubscriberTest { private val ably = mockk(relaxed = true) private val trackableId = UUID.randomUUID().toString() - private val subscriber = DefaultSubscriber(ably, null, trackableId) + private val subscriber = DefaultSubscriber(ably, null, trackableId, null) @Test(expected = ConnectionException::class) fun `should return an error when starting the subscriber with subscribing to presence error`() {