style(android): consolidate ResumeController.restore returns into runCatching
restore() had 3 explicit returns (row null + decode-failure + empty
tracks) — over detekt's ReturnCount limit of 2. Folded the decode
+ empty-check into a single runCatching chain:
runCatching { decode }
.onFailure { dao.clear() side-effect }
.getOrNull()
?.takeIf { tracks.isNotEmpty() }
?: return
Two returns now (row missing + the chain result null). Cleaner read
too — the side effect of dropping a corrupt row is right next to the
decode it guards.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
|||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.SerializationException
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -41,21 +40,25 @@ class ResumeController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun restore() {
|
suspend fun restore() {
|
||||||
|
// runCatching folds row-missing + decode-failure + empty-tracks into
|
||||||
|
// a single null-or-go-ahead expression so detekt's ReturnCount rule
|
||||||
|
// is satisfied. The .onFailure side effect drops a corrupted row
|
||||||
|
// rather than leaving a poison pill across launches.
|
||||||
val row = dao.get() ?: return
|
val row = dao.get() ?: return
|
||||||
val payload =
|
val payload =
|
||||||
try {
|
runCatching { json.decodeFromString<ResumePayload>(row.json) }
|
||||||
json.decodeFromString<ResumePayload>(row.json)
|
.onFailure {
|
||||||
} catch (e: SerializationException) {
|
Timber.w(it, "ResumeController: dropping unreadable resume state")
|
||||||
// Schema drift or corruption — drop the row and start clean
|
dao.clear()
|
||||||
// rather than crashing or leaving a poison pill.
|
}
|
||||||
Timber.w(e, "ResumeController: dropping unreadable resume state")
|
.getOrNull()
|
||||||
dao.clear()
|
?.takeIf { it.tracks.isNotEmpty() }
|
||||||
return
|
?: return
|
||||||
}
|
|
||||||
if (payload.tracks.isEmpty()) return
|
|
||||||
playerController.setQueue(
|
playerController.setQueue(
|
||||||
tracks = payload.tracks,
|
tracks = payload.tracks,
|
||||||
initialIndex = payload.queueIndex.coerceAtLeast(0).coerceAtMost(payload.tracks.lastIndex),
|
initialIndex = payload.queueIndex
|
||||||
|
.coerceAtLeast(0)
|
||||||
|
.coerceAtMost(payload.tracks.lastIndex),
|
||||||
source = payload.source,
|
source = payload.source,
|
||||||
)
|
)
|
||||||
// PositionMs not seeked yet — Player connection may still be
|
// PositionMs not seeked yet — Player connection may still be
|
||||||
|
|||||||
Reference in New Issue
Block a user