better support for code-based exceptions
This commit is contained in:
parent
a0dce8e604
commit
7871dc2d3d
@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "net.sergeych"
|
||||
version = "0.5.1-SNAPSHOT"
|
||||
version = "0.5.2-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@ -52,7 +52,7 @@ kotlin {
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.2")
|
||||
api("io.ktor:ktor-client-core:$ktor_version")
|
||||
api("net.sergeych:crypto2:0.7.1+")
|
||||
api("net.sergeych:crypto2:0.7.1-SNAPSHOT")
|
||||
}
|
||||
}
|
||||
val ktorSocketMain by creating {
|
||||
|
@ -0,0 +1,6 @@
|
||||
package net.sergeych.kiloparsec
|
||||
|
||||
interface ExceptionWithCode {
|
||||
val code: String
|
||||
val message: String?
|
||||
}
|
@ -106,7 +106,8 @@ open class LocalInterface<S> : Loggable by LogTag("LocalInterface${idCounter.inc
|
||||
}
|
||||
|
||||
fun getErrorCode(t: Throwable): String? =
|
||||
errorByClass[t::class] ?: errorProviders.firstNonNull { it.getErrorCode(t) }
|
||||
(t as? ExceptionWithCode)?.code
|
||||
?: errorByClass[t::class] ?: errorProviders.firstNonNull { it.getErrorCode(t) }
|
||||
|
||||
fun encodeError(forId: UInt, t: Throwable): Transport.Block.Error =
|
||||
if (t is RemoteInterface.ClosedException) {
|
||||
|
@ -124,7 +124,7 @@ class Transport<S>(
|
||||
}
|
||||
|
||||
// now we have mutex freed so we can call:
|
||||
val r = runCatching { device.output.send(pack(b).also { debug { ">>>\n${it.toDump()}" } }) }
|
||||
val r = runCatching { device.output.send(pack(b)) }
|
||||
if (!r.isSuccess) {
|
||||
r.exceptionOrNull()?.let {
|
||||
exception { "failed to send output block" to it }
|
||||
@ -184,10 +184,7 @@ class Transport<S>(
|
||||
while (isActive && !isClosed) {
|
||||
try {
|
||||
device.input.receive().let { packed ->
|
||||
debug { "<<<\n${packed.toDump()}" }
|
||||
val b = unpack<Block>(packed)
|
||||
debug { "<<$ $b" }
|
||||
debug { "access state: ${access.isLocked}" }
|
||||
when (b) {
|
||||
is Block.Error -> access.withLock {
|
||||
val error = localInterface.decodeError(b)
|
||||
@ -199,7 +196,7 @@ class Transport<S>(
|
||||
|
||||
is Block.Response -> access.withLock {
|
||||
calls.remove(b.forId)?.let {
|
||||
debug { "activating wait handle for ${b.forId}" }
|
||||
// debug { "activating wait handle for ${b.forId}" }
|
||||
it.complete(b.packedResult)
|
||||
}
|
||||
?: warning { "wait handle not found for ${b.forId}" }
|
||||
@ -228,11 +225,10 @@ class Transport<S>(
|
||||
} catch (t: Throwable) {
|
||||
send(Block.Error(b.id, "UnknownError", t.message))
|
||||
}
|
||||
.also { debug { "command executed: ${b.name}" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
debug { "input step performed closed=$isClosed active=$isActive" }
|
||||
// debug { "input step performed closed=$isClosed active=$isActive" }
|
||||
} catch (_: ClosedSendChannelException) {
|
||||
info { "closed send channel" }
|
||||
isClosed = true
|
||||
|
@ -10,7 +10,6 @@ import kotlinx.coroutines.channels.ClosedReceiveChannelException
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import net.sergeych.crypto2.SigningKey
|
||||
import net.sergeych.crypto2.toDump
|
||||
import net.sergeych.kiloparsec.KiloInterface
|
||||
import net.sergeych.kiloparsec.KiloServerConnection
|
||||
import net.sergeych.kiloparsec.RemoteInterface
|
||||
@ -86,9 +85,7 @@ fun <S> Application.setupWebsocketServer(
|
||||
log.debug { "incoming frame: ${f.frameType}" }
|
||||
if (f is Frame.Binary)
|
||||
try {
|
||||
input.send(f.readBytes().toUByteArray().also {
|
||||
log.debug { "in frame\n${it.toDump()}" }
|
||||
})
|
||||
input.send(f.readBytes().toUByteArray())
|
||||
} catch (_: RemoteInterface.ClosedException) {
|
||||
log.warning { "caught local closed exception (strange!), closing" }
|
||||
break
|
||||
|
Loading…
x
Reference in New Issue
Block a user