捕获 Scala 进程失败

Catching Scala Process failures

我有一个基于 Scala 的 RESTful API。其中一条路线调用外部命令并使用 ProcessLogger 捕获输出。当我在服务器上施加少量负载(通过单元测试)时,外部命令调用开始间歇性失败。没有响应返回并且 HTTP 请求超时。 Process 调用的 return 代码未填充,没有抛出异常...我无法在日志中捕获或找到任何内容。 有没有一种特定的方法可以捕获 scala 中进程调用的所有问题,这可能有助于我调试正在发生的事情?

我的代码是这样的...

try { 
  var resultCode:Int = 
    (Seq("echo",data) #| 
      Seq("external-command-to-call")) !
      ProcessLogger(stdout append _, stderr append _)

  println("Output "+resultCode)
  println(stderr)
  println(stdout)

  // check return code
  if(resultCode > 0) {
    Left("An error occurred")
  }
} catch {
   case e: Exception => {
     Left("An exception occurred")
   }
}

10 次中有 9 次它会打印 "Output",但它会间歇性地在外部调用时死掉,从不打印 "Output"。 "Left" 都没有被触发。 我尝试使用 Try/Success/Failure 并捕获 "Throwable" 但没有任何乐趣。

这只是我的一个想法。 我们不能使用 Scala Futures 来解决这个问题吗:) 我希望你可以使用 Future onFailure 来处理这种情况。 我在 Whosebug 中找到了这篇关于 Scala Process Logger 的类似文章,希望这对您有所帮助。 Scala ProcessLogger & Future: How can I make sure all line callbacks are called BEFORE the onComplete block?

Scala 的未来[T]

当 Future 完成并带有一个值时,它是成功完成的。 如果 Future 完成但出现异常,则它是失败的。 https://docs.scala-lang.org/overviews/core/futures.html

`val f: Future[List[String]] = Future {
  session.getRecentPosts
}

f onFailure {
  case t => println("An error has occured: " + t.getMessage)
}

f onSuccess {
  case posts => for (post <- posts) println(post)
} `

所以问题可以使用 Scala 的 Future monad 来解决,你需要做的是将那些 processLogger 方法更改为 return Future[Int] 现在你不应该使用 Future 的 onSuccess 和 onFailure 方法作为它们已被弃用,因此您可以通过在此 Future 上添加回调来确保它。 通过使用 onCompletemapforeach

result.onComplete{
case Success(x) => println(x)

case Failure(ex)=>ex.printStackTrace}