some docs

This commit is contained in:
Sergey Chernov 2022-09-08 08:40:24 +03:00
parent ceb6ea53db
commit 0ed084aeee
2 changed files with 15 additions and 6 deletions

View File

@ -3,7 +3,8 @@ package net.sergeych.parsec3
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**
* Registry to restore exceptions from parsec block data. Serializing exceptions is dangerous: being a OS-bound * Registry to restore exceptions from parsec block data and encode them to.
* Serializing exceptions is dangerous: being a OS-bound
* objects, exceptions can carry too much sensitive or useless information (e.g. call stack), and serializng * objects, exceptions can carry too much sensitive or useless information (e.g. call stack), and serializng
* actual exceptions could be a pain, so parsec3 serializes exception information as 2 parameters: a code string * actual exceptions could be a pain, so parsec3 serializes exception information as 2 parameters: a code string
* which is very much like old good (and awful in a way) `C ERRNO`, and an optional message. * which is very much like old good (and awful in a way) `C ERRNO`, and an optional message.
@ -14,22 +15,26 @@ import kotlin.reflect.KClass
* *
* The good idea is to share one object inheriting from refistry to hold all exceptions info in one place * The good idea is to share one object inheriting from refistry to hold all exceptions info in one place
* and share it betweem client and server code. * and share it betweem client and server code.
*
* Note that exception registry is used to properly serialize registered exceptions, so as soon as you have
* registered some code and exception, you can throw it inside command implementation and it will be
* properly resotred on the remote side.
*/ */
open class ExceptionsRegistry { open class ExceptionsRegistry {
val handlers = mutableMapOf<String,(String?)->Throwable>().also { val handlers = mutableMapOf<String, (String?) -> Throwable>().also {
// predefined exceptions: // predefined exceptions:
it[commandNotFoundCode] = { CommandNotFoundException(it ?: "???") } it[commandNotFoundCode] = { CommandNotFoundException(it ?: "???") }
it[unknownErrorCode] = { UnknownException(it ?: "???") } it[unknownErrorCode] = { UnknownException(it ?: "???") }
} }
val classCodes = mutableMapOf<KClass<*>,String>() val classCodes = mutableMapOf<KClass<*>, String>()
/** /**
* Register an exception with a code with a handler that creates its instance. Note that the * Register an exception with a code with a handler that creates its instance. Note that the
* handler _should not throw anything_ but rather create an instance of the exception. * handler _should not throw anything_ but rather create an instance of the exception.
*/ */
inline fun <reified T: Throwable>register(code: String, noinline block: (message: String?) -> T) { inline fun <reified T : Throwable> register(code: String, noinline block: (message: String?) -> T) {
handlers[code] = block handlers[code] = block
classCodes[T::class] = code classCodes[T::class] = code
} }
@ -38,14 +43,14 @@ open class ExceptionsRegistry {
* raise the exception using the proper handler. Throws [UnknownCodeException] of there is no handler * raise the exception using the proper handler. Throws [UnknownCodeException] of there is no handler
* for a given code. * for a given code.
*/ */
internal fun raise(code: String,message: String?): Nothing { internal fun raise(code: String, message: String?): Nothing {
throw getException(code, message) throw getException(code, message)
} }
/** /**
* create the exception instanceusing the proper handler, or an [UnknownCodeException] if handler not found * create the exception instanceusing the proper handler, or an [UnknownCodeException] if handler not found
*/ */
internal fun getException(code: String,message: String?): Throwable = internal fun getException(code: String, message: String?): Throwable =
handlers[code]?.let { it(message) } ?: UnknownCodeException(code, message) handlers[code]?.let { it(message) } ?: UnknownCodeException(code, message)
companion object { companion object {

View File

@ -10,6 +10,10 @@ import java.time.Duration
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicLong
/**
* Creates a ktor server initialization module capable to perform p3 transport layer (not secure).
* It could be used as is or as transport for p3.1
*/
fun <S, H : CommandHost<S>>Application.parsec3TransportServer( fun <S, H : CommandHost<S>>Application.parsec3TransportServer(
api: H, api: H,
exceptionsRegistry: ExceptionsRegistry = ExceptionsRegistry(), exceptionsRegistry: ExceptionsRegistry = ExceptionsRegistry(),