diff --git a/app/src/main/java/io/heckel/ntfy/db/Database.kt b/app/src/main/java/io/heckel/ntfy/db/Database.kt index 23677fd8..fa414edf 100644 --- a/app/src/main/java/io/heckel/ntfy/db/Database.kt +++ b/app/src/main/java/io/heckel/ntfy/db/Database.kt @@ -20,9 +20,9 @@ import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import com.google.gson.Gson import com.google.gson.reflect.TypeToken +import io.heckel.ntfy.service.isConnectionRefused import kotlinx.coroutines.flow.Flow import java.lang.reflect.Type -import java.net.ConnectException @Entity(indices = [Index(value = ["baseUrl", "topic"], unique = true), Index(value = ["upConnectorToken"], unique = true)]) data class Subscription( @@ -105,16 +105,7 @@ data class ConnectionDetails( } fun isConnectionRefused(): Boolean { - return hasCauseOfType() - } - - private inline fun hasCauseOfType(): Boolean { - var current: Throwable? = error - while (current != null) { - if (current is T) return true - current = current.cause - } - return false + return error?.let { isConnectionRefused(it) } ?: false } } diff --git a/app/src/main/java/io/heckel/ntfy/service/Connection.kt b/app/src/main/java/io/heckel/ntfy/service/Connection.kt index f195fade..855f00b7 100644 --- a/app/src/main/java/io/heckel/ntfy/service/Connection.kt +++ b/app/src/main/java/io/heckel/ntfy/service/Connection.kt @@ -2,6 +2,7 @@ package io.heckel.ntfy.service import okhttp3.internal.http2.StreamResetException import java.io.EOFException +import java.net.ConnectException interface Connection { fun start() @@ -24,9 +25,30 @@ data class ConnectionId( val reconnectVersion: Long // Incremented to force reconnection for this baseUrl ) -fun isConnectionBrokenException(t: Throwable): Boolean { - return t is EOFException - || t.cause is EOFException - || t is StreamResetException - || t.cause is StreamResetException +/** + * Checks if the throwable or any of its causes is of the specified type. + */ +inline fun Throwable.hasCause(): Boolean { + var current: Throwable? = this + while (current != null) { + if (current is T) return true + current = current.cause + } + return false +} + +/** + * Returns true if the exception indicates the connection was broken normally + * (e.g., server closed connection). These errors should not be shown to the user. + */ +fun isConnectionBrokenException(t: Throwable): Boolean { + return t.hasCause() || t.hasCause() +} + +/** + * Returns true if the exception indicates the connection was refused + * (e.g., server is down or address is incorrect). + */ +fun isConnectionRefused(t: Throwable): Boolean { + return t.hasCause() } diff --git a/app/src/main/java/io/heckel/ntfy/service/JsonConnection.kt b/app/src/main/java/io/heckel/ntfy/service/JsonConnection.kt index ab02dc14..8cf2268e 100644 --- a/app/src/main/java/io/heckel/ntfy/service/JsonConnection.kt +++ b/app/src/main/java/io/heckel/ntfy/service/JsonConnection.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import okhttp3.Call -import java.io.EOFException import kotlin.random.Random class JsonConnection( diff --git a/app/src/main/java/io/heckel/ntfy/service/WsConnection.kt b/app/src/main/java/io/heckel/ntfy/service/WsConnection.kt index 24b9f633..0443c96c 100644 --- a/app/src/main/java/io/heckel/ntfy/service/WsConnection.kt +++ b/app/src/main/java/io/heckel/ntfy/service/WsConnection.kt @@ -17,7 +17,6 @@ import okhttp3.OkHttpClient import okhttp3.Response import okhttp3.WebSocket import okhttp3.WebSocketListener -import java.io.EOFException import java.util.Calendar import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicReference