mirror of
https://github.com/recloudstream/cloudstream.git
synced 2025-08-06 11:31:45 +08:00
Updated the safe function for more ergonomic code
This commit is contained in:
@ -3,6 +3,7 @@ package com.lagradost.cloudstream3.mvvm
|
|||||||
import com.lagradost.api.BuildConfig
|
import com.lagradost.api.BuildConfig
|
||||||
import com.lagradost.api.Log
|
import com.lagradost.api.Log
|
||||||
import com.lagradost.cloudstream3.ErrorLoadingException
|
import com.lagradost.cloudstream3.ErrorLoadingException
|
||||||
|
import com.lagradost.cloudstream3.Prerelease
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.io.InterruptedIOException
|
import java.io.InterruptedIOException
|
||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
@ -67,6 +68,7 @@ fun logError(throwable: Throwable) {
|
|||||||
Log.d("ApiError", "-------------------------------------------------------------------")
|
Log.d("ApiError", "-------------------------------------------------------------------")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Outdated function, use `safe` instead when the new stable is released", ReplaceWith("safe"), level = DeprecationLevel.WARNING)
|
||||||
fun <T> normalSafeApiCall(apiCall: () -> T): T? {
|
fun <T> normalSafeApiCall(apiCall: () -> T): T? {
|
||||||
return try {
|
return try {
|
||||||
apiCall.invoke()
|
apiCall.invoke()
|
||||||
@ -76,6 +78,31 @@ fun <T> normalSafeApiCall(apiCall: () -> T): T? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Catches any exception (or error) and only logs it.
|
||||||
|
* Will return null on exceptions. */
|
||||||
|
@Prerelease
|
||||||
|
fun <T> safe(apiCall: () -> T): T? {
|
||||||
|
return try {
|
||||||
|
apiCall.invoke()
|
||||||
|
} catch (throwable: Throwable) {
|
||||||
|
logError(throwable)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Catches any exception (or error) and only logs it.
|
||||||
|
* Will return null on exceptions. */
|
||||||
|
@Prerelease
|
||||||
|
suspend fun <T> safeAsync(apiCall: suspend () -> T): T? {
|
||||||
|
return try {
|
||||||
|
apiCall.invoke()
|
||||||
|
} catch (throwable: Throwable) {
|
||||||
|
logError(throwable)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Outdated function, use `safeAsync` instead when the new stable is released", ReplaceWith("safeAsync"), level = DeprecationLevel.WARNING)
|
||||||
suspend fun <T> suspendSafeApiCall(apiCall: suspend () -> T): T? {
|
suspend fun <T> suspendSafeApiCall(apiCall: suspend () -> T): T? {
|
||||||
return try {
|
return try {
|
||||||
apiCall.invoke()
|
apiCall.invoke()
|
||||||
@ -119,7 +146,7 @@ fun CoroutineScope.launchSafe(
|
|||||||
return this.launch(context, start, obj)
|
return this.launch(context, start, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun<T> throwAbleToResource(
|
fun <T> throwAbleToResource(
|
||||||
throwable: Throwable
|
throwable: Throwable
|
||||||
): Resource<T> {
|
): Resource<T> {
|
||||||
return when (throwable) {
|
return when (throwable) {
|
||||||
@ -131,6 +158,7 @@ fun<T> throwAbleToResource(
|
|||||||
"App or extension is outdated, update the app or try pre-release.\n${throwable.message}" // todo add exact version?
|
"App or extension is outdated, update the app or try pre-release.\n${throwable.message}" // todo add exact version?
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is NullPointerException -> {
|
is NullPointerException -> {
|
||||||
for (line in throwable.stackTrace) {
|
for (line in throwable.stackTrace) {
|
||||||
if (line?.fileName?.endsWith("provider.kt", ignoreCase = true) == true) {
|
if (line?.fileName?.endsWith("provider.kt", ignoreCase = true) == true) {
|
||||||
@ -144,6 +172,7 @@ fun<T> throwAbleToResource(
|
|||||||
}
|
}
|
||||||
safeFail(throwable)
|
safeFail(throwable)
|
||||||
}
|
}
|
||||||
|
|
||||||
is SocketTimeoutException, is InterruptedIOException -> {
|
is SocketTimeoutException, is InterruptedIOException -> {
|
||||||
Resource.Failure(
|
Resource.Failure(
|
||||||
true,
|
true,
|
||||||
@ -161,8 +190,14 @@ fun<T> throwAbleToResource(
|
|||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
is UnknownHostException -> {
|
is UnknownHostException -> {
|
||||||
Resource.Failure(true, null, null, "Cannot connect to server, try again later.\n${throwable.message}")
|
Resource.Failure(
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"Cannot connect to server, try again later.\n${throwable.message}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is ErrorLoadingException -> {
|
is ErrorLoadingException -> {
|
||||||
Resource.Failure(
|
Resource.Failure(
|
||||||
true,
|
true,
|
||||||
@ -171,9 +206,11 @@ fun<T> throwAbleToResource(
|
|||||||
throwable.message ?: "Error loading, try again later."
|
throwable.message ?: "Error loading, try again later."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is NotImplementedError -> {
|
is NotImplementedError -> {
|
||||||
Resource.Failure(false, null, null, "This operation is not implemented.")
|
Resource.Failure(false, null, null, "This operation is not implemented.")
|
||||||
}
|
}
|
||||||
|
|
||||||
is SSLHandshakeException -> {
|
is SSLHandshakeException -> {
|
||||||
Resource.Failure(
|
Resource.Failure(
|
||||||
true,
|
true,
|
||||||
@ -182,11 +219,13 @@ fun<T> throwAbleToResource(
|
|||||||
(throwable.message ?: "SSLHandshakeException") + "\nTry a VPN or DNS."
|
(throwable.message ?: "SSLHandshakeException") + "\nTry a VPN or DNS."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is CancellationException -> {
|
is CancellationException -> {
|
||||||
throwable.cause?.let {
|
throwable.cause?.let {
|
||||||
throwAbleToResource(it)
|
throwAbleToResource(it)
|
||||||
} ?: safeFail(throwable)
|
} ?: safeFail(throwable)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> safeFail(throwable)
|
else -> safeFail(throwable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user