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