1

我有这样的入口点:

def main(args: Array[String]): Unit = {
  pureconfig.loadConfig[Conf] match {
    case Right(conf) => doStuff(conf)
    case Left(fail) => lectureUserAboutStuff(fail)
  }
}

所以看起来我的程序的主要目的是加载配置,这是不正确的,我的程序的核心是doStuff.

如何表达这一点并隐藏秘密配置?

我想要这样的东西:

def main(args: Array[String]): Unit = {
  doStuff(conf)(failHandler)
}

其中很明显,故障处理和配置加载只是附件。

4

1 回答 1

1

从程序的方法中使用 PureConfig 的最常见main方法之一是在出现错误时快速失败。loadConfigOrThrow如果加载成功,API 提供返回配置,ConfigReaderException否则抛出:

import pureconfig.loadConfigOrThrow

def main(args: Array[String]): Unit = {
  val conf = loadConfigOrThrow[Conf] // will throw if Conf cannot be loaded
  doStuff(conf)
}

pureconfig.loadConfig返回 an的原因Either是因为加载配置可能会失败。Either用 建模失败案例,用 建模Left成功案例Right。这对库很有用,因为您永远不知道loadConfig 将在哪里调用,因此您不想抛出异常。虽然这通常是正确的,loadConfig但从“表面”方法使用 when 是有意义的,例如main,抛出异常或在配置加载失败的情况下退出是有意义的,这就是 pureconfig 提供的原因loadConfigOrThrow

如果您不喜欢抛出异常或者您更喜欢自定义故障处理程序,例如lectureUserAboutStuff,您可以创建一个帮助程序:

def loadConfig(): Option[Conf] = {
  val errorOrConf = pureconfig.loadConfig[Conf]
  errorOrConf.left.foreach(lectureUserAboutStuff)
  errorOrConf.toOption
}

def main(args: Array[String]): Unit =
  loadConfig().foreach(doStuff)

最后要记住的一点是,此代码的一个小问题是应用程序的退出代码不受配置失败的影响。如果要在无法加载配置时设置退出代码,则更main改为

val configReaderFailureErrorCode = 42

private def configFailureExit() =
  sys.exit(configReaderFailureErrorCode)

def main(args: Array[String]): Unit =
  loadConfig().fold(configFailureExit())(doStuff)
于 2017-10-21T11:46:40.987 回答