From e31d59f63ebe5536d2d2d868703eb8896924b63d Mon Sep 17 00:00:00 2001 From: Piotr Jaszczyk Date: Wed, 4 Jul 2018 13:16:21 +0200 Subject: [PATCH] Use IO monad when starting servers Change-Id: I3e97161535fc721dda6109c4cb5f23a1db0afde3 Signed-off-by: Piotr Jaszczyk Issue-ID: DCAEGEN2-601 --- .../dcae/collectors/veshv/simulators/xnf/main.kt | 34 +++++++-------- .../main/config/ArgBasedClientConfigurationTest.kt | 13 +++--- .../collectors/veshv/simulators/dcaeapp/main.kt | 34 +++++++++------ .../config/ArgBasedDcaeAppSimConfigurationTest.kt | 31 +++++++------- .../org/onap/dcae/collectors/veshv/main/main.kt | 44 +++++++++++-------- .../veshv/main/ArgBasedServerConfigurationTest.kt | 13 +++--- hv-collector-utils/pom.xml | 8 ++++ .../onap/dcae/collectors/veshv/utils/arrow/core.kt | 31 ++++++++++++++ .../dcae/collectors/veshv/utils/arrow/effects.kt | 49 ++++++++++++++++++++++ .../utils/commandline/ArgBasedConfiguration.kt | 15 ++++--- ...gArgumentException.kt => WrongArgumentError.kt} | 7 ++-- .../veshv/utils/commandline/extensions.kt | 30 ++++--------- 12 files changed, 197 insertions(+), 112 deletions(-) create mode 100644 hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt create mode 100644 hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/effects.kt rename hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/{WrongArgumentException.kt => WrongArgumentError.kt} (92%) diff --git a/hv-collector-client-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt b/hv-collector-client-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt index dbeba2b2..63c48757 100644 --- a/hv-collector-client-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt +++ b/hv-collector-client-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/main.kt @@ -19,38 +19,36 @@ */ package org.onap.dcae.collectors.veshv.simulators.xnf -import arrow.core.Failure -import arrow.core.Success import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgBasedClientConfiguration import org.onap.dcae.collectors.veshv.simulators.xnf.impl.HttpServer import org.onap.dcae.collectors.veshv.simulators.xnf.impl.VesHvClient -import org.onap.dcae.collectors.veshv.utils.commandline.handleErrorsInMain +import org.onap.dcae.collectors.veshv.utils.arrow.ExitFailure +import org.onap.dcae.collectors.veshv.utils.arrow.unsafeRunEitherSync +import org.onap.dcae.collectors.veshv.utils.arrow.void +import org.onap.dcae.collectors.veshv.utils.commandline.handleWrongArgumentErrorCurried import org.onap.dcae.collectors.veshv.utils.logging.Logger +import org.slf4j.LoggerFactory - -private val logger = Logger("Simulator :: main") -private const val PROGRAM_NAME = "java org.onap.dcae.collectors.veshv.main.MainKt" +private const val PACKAGE_NAME = "org.onap.dcae.collectors.veshv.simulators.xnf" +private val logger = Logger(PACKAGE_NAME) +const val PROGRAM_NAME = "java $PACKAGE_NAME.MainKt" /** * @author Jakub Dudycz * @since June 2018 */ -fun main(args: Array) { - val httpServer = ArgBasedClientConfiguration().parse(args) +fun main(args: Array) = + ArgBasedClientConfiguration().parse(args) + .mapLeft(handleWrongArgumentErrorCurried(PROGRAM_NAME)) .map(::VesHvClient) .map(::HttpServer) - - when (httpServer) { - is Success -> httpServer.value.start().unsafeRunAsync { - it.fold( + .map { it.start().void() } + .unsafeRunEitherSync( { ex -> logger.error("Failed to start a server", ex) + ExitFailure(1) }, - { srv -> - logger.info("Started Simulator API server (listening on ${srv.bindHost}:${srv.bindPort})") + { + logger.info("Started xNF Simulator API server") } ) - } - is Failure -> httpServer.handleErrorsInMain(PROGRAM_NAME, logger) - } -} diff --git a/hv-collector-client-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgBasedClientConfigurationTest.kt b/hv-collector-client-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgBasedClientConfigurationTest.kt index 2746c0a6..3b1836eb 100644 --- a/hv-collector-client-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgBasedClientConfigurationTest.kt +++ b/hv-collector-client-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgBasedClientConfigurationTest.kt @@ -21,6 +21,7 @@ package org.onap.dcae.collectors.veshv.main.config import arrow.core.Failure import arrow.core.Success +import arrow.core.identity import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe @@ -46,13 +47,11 @@ object ArgBasedClientConfigurationTest : Spek({ cut = ArgBasedClientConfiguration() } - fun parse(vararg cmdLine: String): ClientConfiguration { - val result = cut.parse(cmdLine) - return when (result) { - is Success -> result.value - is Failure -> throw AssertionError("Parsing result should be present") - } - } + fun parse(vararg cmdLine: String): ClientConfiguration = + cut.parse(cmdLine).fold( + {throw AssertionError("Parsing result should be present")}, + ::identity + ) describe("parsing arguments") { lateinit var result: ClientConfiguration diff --git a/hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/main.kt b/hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/main.kt index f7d44ede..a8a4cf5a 100644 --- a/hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/main.kt +++ b/hv-collector-dcae-app-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/main.kt @@ -19,30 +19,38 @@ */ package org.onap.dcae.collectors.veshv.simulators.dcaeapp -import arrow.core.Failure -import arrow.core.Success import org.onap.dcae.collectors.veshv.simulators.dcaeapp.config.ArgBasedDcaeAppSimConfiguration import org.onap.dcae.collectors.veshv.simulators.dcaeapp.config.DcaeAppSimConfiguration import org.onap.dcae.collectors.veshv.simulators.dcaeapp.kafka.KafkaSource import org.onap.dcae.collectors.veshv.simulators.dcaeapp.remote.ApiServer -import org.onap.dcae.collectors.veshv.utils.commandline.handleErrorsInMain +import org.onap.dcae.collectors.veshv.utils.arrow.ExitFailure +import org.onap.dcae.collectors.veshv.utils.arrow.unsafeRunEitherSync +import org.onap.dcae.collectors.veshv.utils.arrow.void +import org.onap.dcae.collectors.veshv.utils.commandline.handleWrongArgumentErrorCurried import org.onap.dcae.collectors.veshv.utils.logging.Logger import org.slf4j.LoggerFactory -private val logger = Logger(LoggerFactory.getLogger("DCAE simulator :: main")) +private const val PACKAGE_NAME = "org.onap.dcae.collectors.veshv.simulators.dcaeapp" +private val logger = Logger(PACKAGE_NAME) +const val PROGRAM_NAME = "java $PACKAGE_NAME.MainKt" -fun main(args: Array) { - logger.info("Starting DCAE APP simulator") +fun main(args: Array) = + ArgBasedDcaeAppSimConfiguration().parse(args) + .mapLeft(handleWrongArgumentErrorCurried(PROGRAM_NAME)) + .map(::startApp) + .unsafeRunEitherSync( + { ex -> + logger.error("Failed to start a server", ex) + ExitFailure(1) + }, + { + logger.info("Started DCAE-APP Simulator API server") + } + ) - val config = ArgBasedDcaeAppSimConfiguration().parse(args) - when (config) { - is Success -> startApp(config.value).unsafeRunSync() - is Failure -> config.handleErrorsInMain("", logger) - } -} private fun startApp(config: DcaeAppSimConfiguration) = KafkaSource.create(config.kafkaBootstrapServers, config.kafkaTopics) .start() .map(::ApiServer) - .flatMap { it.start(config.apiPort) } + .flatMap { it.start(config.apiPort).void() } diff --git a/hv-collector-dcae-app-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/config/ArgBasedDcaeAppSimConfigurationTest.kt b/hv-collector-dcae-app-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/config/ArgBasedDcaeAppSimConfigurationTest.kt index d99de17b..b73a788e 100644 --- a/hv-collector-dcae-app-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/config/ArgBasedDcaeAppSimConfigurationTest.kt +++ b/hv-collector-dcae-app-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/simulators/dcaeapp/config/ArgBasedDcaeAppSimConfigurationTest.kt @@ -21,12 +21,13 @@ package org.onap.dcae.collectors.veshv.simulators.dcaeapp.config import arrow.core.Failure import arrow.core.Success +import arrow.core.identity import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it -import org.onap.dcae.collectors.veshv.utils.commandline.WrongArgumentException +import org.onap.dcae.collectors.veshv.utils.commandline.WrongArgumentError internal class ArgBasedDcaeAppSimConfigurationTest : Spek({ @@ -39,21 +40,17 @@ internal class ArgBasedDcaeAppSimConfigurationTest : Spek({ cut = ArgBasedDcaeAppSimConfiguration() } - fun parseExpectingSuccess(vararg cmdLine: String): DcaeAppSimConfiguration { - val result = cut.parse(cmdLine) - return when (result) { - is Success -> result.value - is Failure -> throw AssertionError("Parsing result should be present") - } - } + fun parseExpectingSuccess(vararg cmdLine: String): DcaeAppSimConfiguration = + cut.parse(cmdLine).fold( + { throw AssertionError("Parsing result should be present") }, + ::identity + ) - fun parseExpectingFailure(vararg cmdLine: String): Throwable { - val result = cut.parse(cmdLine) - return when (result) { - is Success -> throw AssertionError("parsing should have failed") - is Failure -> result.exception - } - } + fun parseExpectingFailure(vararg cmdLine: String) = + cut.parse(cmdLine).fold( + ::identity, + { throw AssertionError("parsing should have failed") } + ) describe("parsing arguments") { lateinit var result: DcaeAppSimConfiguration @@ -121,14 +118,14 @@ internal class ArgBasedDcaeAppSimConfigurationTest : Spek({ given("kafka topics are missing") { it("should throw exception") { assertThat(parseExpectingFailure("-s", kafkaBootstrapServers)) - .isInstanceOf(WrongArgumentException::class.java) + .isInstanceOf(WrongArgumentError::class.java) } } given("kafka bootstrap servers are missing") { it("should throw exception") { assertThat(parseExpectingFailure("-f", kafkaTopics)) - .isInstanceOf(WrongArgumentException::class.java) + .isInstanceOf(WrongArgumentError::class.java) } } } diff --git a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt index d1c3b4a7..f5efab2b 100644 --- a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt +++ b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/main.kt @@ -19,34 +19,38 @@ */ package org.onap.dcae.collectors.veshv.main -import arrow.core.flatMap import org.onap.dcae.collectors.veshv.boundary.Server +import org.onap.dcae.collectors.veshv.boundary.ServerHandle import org.onap.dcae.collectors.veshv.factory.CollectorFactory import org.onap.dcae.collectors.veshv.factory.ServerFactory import org.onap.dcae.collectors.veshv.impl.adapters.AdapterFactory import org.onap.dcae.collectors.veshv.model.ServerConfiguration -import org.onap.dcae.collectors.veshv.utils.commandline.handleErrorsInMain +import org.onap.dcae.collectors.veshv.utils.arrow.ExitFailure +import org.onap.dcae.collectors.veshv.utils.arrow.unsafeRunEitherSync +import org.onap.dcae.collectors.veshv.utils.arrow.void +import org.onap.dcae.collectors.veshv.utils.commandline.handleWrongArgumentErrorCurried import org.onap.dcae.collectors.veshv.utils.logging.Logger private val logger = Logger("org.onap.dcae.collectors.veshv.main") private const val PROGRAM_NAME = "java org.onap.dcae.collectors.veshv.main.MainKt" -fun main(args: Array) { - ArgBasedServerConfiguration().parse(args) - .toEither() - .map(::createServer) - .map(Server::start) - .flatMap { it.attempt().unsafeRunSync() } - .fold( - { ex -> - handleErrorsInMain(ex, PROGRAM_NAME, logger) - }, - { handle -> - logger.info("Server started. Listening on ${handle.host}:${handle.port}") - handle.await().unsafeRunSync() - } - ) -} +fun main(args: Array) = + ArgBasedServerConfiguration().parse(args) + .mapLeft(handleWrongArgumentErrorCurried(PROGRAM_NAME)) + .map(::createServer) + .map { + it.start() + .map(::logServerStarted) + .flatMap(ServerHandle::await) + } + .unsafeRunEitherSync( + { ex -> + logger.error("Failed to start a server", ex) + ExitFailure(1) + }, + { logger.info("Gentle shutdown") } + ) + private fun createServer(config: ServerConfiguration): Server { val sink = if (config.dummyMode) AdapterFactory.loggingSink() else AdapterFactory.kafkaSink() @@ -60,3 +64,7 @@ private fun createServer(config: ServerConfiguration): Server { return ServerFactory.createNettyTcpServer(config, collectorProvider) } +private fun logServerStarted(handle: ServerHandle): ServerHandle { + logger.info("HighVolume VES Collector is up and listening on ${handle.host}:${handle.port}") + return handle +} diff --git a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt index a14801da..2c49cf98 100644 --- a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt +++ b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt @@ -21,6 +21,7 @@ package org.onap.dcae.collectors.veshv.main import arrow.core.Failure import arrow.core.Success +import arrow.core.identity import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe @@ -49,13 +50,11 @@ object ArgBasedServerConfigurationTest : Spek({ cut = ArgBasedServerConfiguration() } - fun parse(vararg cmdLine: String): ServerConfiguration { - val result = cut.parse(cmdLine) - return when (result) { - is Success -> result.value - is Failure -> throw AssertionError("Parsing result should be present") - } - } + fun parse(vararg cmdLine: String): ServerConfiguration = + cut.parse(cmdLine).fold( + {throw AssertionError("Parsing result should be present")}, + ::identity + ) describe("parsing arguments") { given("all parameters are present in the long form") { diff --git a/hv-collector-utils/pom.xml b/hv-collector-utils/pom.xml index 3c48280c..ea19ba3f 100644 --- a/hv-collector-utils/pom.xml +++ b/hv-collector-utils/pom.xml @@ -71,6 +71,14 @@ io.arrow-kt arrow-instances-data + + io.arrow-kt + arrow-effects + + + io.arrow-kt + arrow-syntax + org.slf4j slf4j-api diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt new file mode 100644 index 00000000..39964c1e --- /dev/null +++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/core.kt @@ -0,0 +1,31 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2018 NOKIA + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.dcae.collectors.veshv.utils.arrow + +import arrow.core.Either +import arrow.core.identity + +/** + * @author Piotr Jaszczyk + * @since July 2018 + */ + + +fun Either.flatten() = fold(::identity, ::identity) diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/effects.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/effects.kt new file mode 100644 index 00000000..e37b0d7d --- /dev/null +++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/arrow/effects.kt @@ -0,0 +1,49 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2018 NOKIA + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.dcae.collectors.veshv.utils.arrow + +import arrow.core.Either +import arrow.effects.IO +import kotlin.system.exitProcess + +/** + * @author Piotr Jaszczyk + * @since June 2018 + */ + +sealed class ExitCode { + abstract val code: Int + + fun io() = IO { + exitProcess(code) + } +} + +object ExitSuccess : ExitCode() { + override val code = 0 +} + +data class ExitFailure(override val code: Int) : ExitCode() + +fun Either, IO>.unsafeRunEitherSync(onError: (Throwable) -> ExitCode, onSuccess: () -> Unit) = + flatten().attempt().unsafeRunSync().fold({ onError(it).io().unsafeRunSync() }, { onSuccess() }) + + +fun IO.void() = map { Unit } diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt index 34c0e651..d5855caa 100644 --- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt +++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/ArgBasedConfiguration.kt @@ -19,6 +19,7 @@ */ package org.onap.dcae.collectors.veshv.utils.commandline +import arrow.core.Either import arrow.core.Option import arrow.core.Try import arrow.core.getOrElse @@ -30,16 +31,18 @@ import java.io.File import java.nio.file.Path import java.nio.file.Paths -abstract class ArgBasedConfiguration(val parser: CommandLineParser) { +abstract class ArgBasedConfiguration(private val parser: CommandLineParser) { abstract val cmdLineOptionsList: List - fun parse(args: Array): Try { + fun parse(args: Array): Either { val commandLineOptions = cmdLineOptionsList.map { it.option }.fold(Options(), Options::addOption) - return Try { + val parseResult = Try { parser.parse(commandLineOptions, args) - }.recoverWith { ex -> - Try.raise(WrongArgumentException(ex, commandLineOptions)) - }.map (this::getConfiguration) + } + return parseResult + .toEither() + .mapLeft { ex -> WrongArgumentError(ex, commandLineOptions) } + .map(this::getConfiguration) } protected abstract fun getConfiguration(cmdLine: CommandLine): T diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/WrongArgumentException.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/WrongArgumentError.kt similarity index 92% rename from hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/WrongArgumentException.kt rename to hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/WrongArgumentError.kt index 083d5798..f3bb3146 100644 --- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/WrongArgumentException.kt +++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/WrongArgumentError.kt @@ -23,11 +23,10 @@ import org.apache.commons.cli.HelpFormatter import org.apache.commons.cli.Options -class WrongArgumentException( - message: String, +data class WrongArgumentError( + val message: String, private val options: Options, - parent: Throwable? = null -) : Exception(message, parent) { + val cause: Throwable? = null) { constructor(par: Throwable, options: Options) : this(par.message ?: "", options, par) diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt index 23bf1658..718ebf8b 100644 --- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt +++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/extensions.kt @@ -19,32 +19,18 @@ */ package org.onap.dcae.collectors.veshv.utils.commandline -import arrow.core.Failure -import org.onap.dcae.collectors.veshv.utils.logging.Logger -import kotlin.system.exitProcess +import arrow.effects.IO +import arrow.syntax.function.curried +import org.onap.dcae.collectors.veshv.utils.arrow.ExitFailure /** * @author Piotr Jaszczyk * @since June 2018 */ -fun handleErrorsInMain(ex: Throwable, programName: String, logger: Logger) { - when (ex) { - is WrongArgumentException -> { - ex.printMessage() - ex.printHelp(programName) - exitProcess(1) - } +fun handleWrongArgumentError(programName: String, err: WrongArgumentError): IO = IO { + err.printMessage() + err.printHelp(programName) +}.flatMap { ExitFailure(2).io() } - else -> { - logger.error(ex.localizedMessage) - logger.debug("An error occurred when starting VES HV Collector", ex) - System.exit(2) - } - } -} - - -fun Failure.handleErrorsInMain(programName: String, logger: Logger) { - handleErrorsInMain(this.exception, programName, logger) -} +val handleWrongArgumentErrorCurried = ::handleWrongArgumentError.curried() -- 2.16.6