Private
Public Access
1
0

Much better error/badconfig handling

This commit is contained in:
2024-03-23 19:01:20 -07:00
parent 611ad15997
commit f266e04895
7 changed files with 101 additions and 45 deletions

View File

@@ -1,12 +1,16 @@
package net.buzzert.kordophone.backend.server
import kotlinx.coroutines.runBlocking
import net.buzzert.kordophone.backend.model.Conversation
import net.buzzert.kordophone.backend.model.GUID
import net.buzzert.kordophone.backend.model.Message
import okhttp3.Authenticator
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.Route
import okhttp3.WebSocket
import okhttp3.WebSocketListener
@@ -71,18 +75,71 @@ class TokenAuthenticator(
apiInterface.authenticate(request).body()
}
if (token == null) {
// Auth failure.
// TODO: How to bubble this up?
return null
when (token) {
null -> {
// Auth failure.
// TODO: How to bubble this up?
return null
}
// Update token store
else -> {
tokenStore.authenticationToken = token.serializedToken
return response.request().newBuilder()
.header("Authorization", "Bearer ${token.serializedToken}")
.build()
}
}
}
}
class APIClientFactory {
companion object {
fun createClient(serverString: String?, authentication: Authentication?): APIClient {
if (serverString == null || authentication == null) {
return InvalidConfigurationAPIClient()
}
// Try to parse server string
val serverURL = HttpUrl.parse(serverString) ?: return InvalidConfigurationAPIClient()
return RetrofitAPIClient(serverURL.url(), authentication)
}
}
}
// TODO: Is this a dumb idea?
class InvalidConfigurationAPIClient: APIClient {
private class InvalidConfigurationAPIInterface: APIInterface {
private fun throwError(): Nothing {
throw Error("Invalid Configuration.")
}
// Update token store
tokenStore.authenticationToken = token.serializedToken
override suspend fun getVersion(): ResponseBody = throwError()
override suspend fun getConversations(): retrofit2.Response<List<Conversation>> = throwError()
override suspend fun sendMessage(request: SendMessageRequest): retrofit2.Response<SendMessageResponse> = throwError()
override suspend fun markConversation(conversationGUID: String): retrofit2.Response<Void> = throwError()
override suspend fun fetchAttachment(guid: String, preview: Boolean): ResponseBody = throwError()
override suspend fun authenticate(request: AuthenticationRequest): retrofit2.Response<AuthenticationResponse> = throwError()
override suspend fun getMessages(
conversationGUID: String,
limit: Int?,
beforeMessageGUID: GUID?,
afterMessageGUID: GUID?
): retrofit2.Response<List<Message>> = throwError()
}
return response.request().newBuilder()
.header("Authorization", "Bearer ${token.serializedToken}")
.build()
override fun getAPIInterface(): APIInterface {
return InvalidConfigurationAPIInterface()
}
override fun getWebSocketClient(
serverPath: String,
queryParams: Map<String, String>?,
listener: WebSocketListener
): WebSocket {
throw Error("Invalid configuration.")
}
}

View File

@@ -41,9 +41,9 @@ class ChatRepository(
open val title: String = "Error"
open val description: String = "Generic Error"
data class ConnectionError(val exception: java.lang.Exception): Error() {
data class ConnectionError(val message: String?): Error() {
override val title: String = "Connection Error"
override val description: String = exception.message ?: "???"
override val description: String = message ?: "???"
}
}
@@ -172,7 +172,9 @@ class ChatRepository(
synchronizeConversation(conversation)
}
} catch (e: java.lang.Exception) {
_errorEncounteredChannel.emit(Error.ConnectionError(e))
_errorEncounteredChannel.emit(Error.ConnectionError(e.message))
} catch (e: java.lang.Error) {
_errorEncounteredChannel.emit(Error.ConnectionError(e.message))
}
suspend fun synchronizeConversation(conversation: Conversation, limit: Int = 15) = try {
@@ -181,7 +183,7 @@ class ChatRepository(
val messages = fetchMessages(conversation, limit = limit)
database.writeMessages(messages, conversation)
} catch (e: java.lang.Exception) {
_errorEncounteredChannel.emit(Error.ConnectionError(e))
_errorEncounteredChannel.emit(Error.ConnectionError(e.message))
}
suspend fun markConversationAsRead(conversation: Conversation) = try {

View File

@@ -41,11 +41,15 @@ class UpdateMonitor(private val client: APIClient) : WebSocketListener() {
fun beginMonitoringUpdates() {
Log.d(UPMON_LOG, "Opening websocket connection")
this.webSocket = client.getWebSocketClient(
serverPath = "updates",
queryParams = mapOf("seq" to messageSeq.toString()),
listener = this
)
try {
this.webSocket = client.getWebSocketClient(
serverPath = "updates",
queryParams = mapOf("seq" to messageSeq.toString()),
listener = this
)
} catch (e: Error) {
Log.e(UPMON_LOG, "Error getting websocket client: ${e.message}")
}
}
fun stopMonitoringForUpdates() {