题 如何捕获任何scalatra动作中的所有错误?


我使用scalatra将MongoDB数据“导出”到JSon,我的操作非常简单,如:

   get("/") {
      val title = db.get_collection("main", "api", "title")
      send_json(title)
    }

如果出现问题,我想发送HTTP错误和文本,另一方面,它将被转换为对用户有意义的东西。 所以方法成为:

   get("/") {
     try {
      val title = db.get_collection("main", "api", "title")
      send_json(title)
     } catch {
      case e:java.util.NoSuchElementException => send_error("DB malformed", InternalError)
      case e:com.mongodb.MongoException => send_error("Can not connect to MongoDB", InternalError)
      case e => send_error("Internal Error", InternalError)
    }
  }

try catch更大,实际的方法和我需要为每个方法执行此操作,该类乍一看是一个丑陋的try catch集合。 有什么方法可以避免或最小化整个代码中的不良外观和分散注意力的尝试捕获?我是Scala(和Java BTW)的新手,所以我想我错过了一些东西。

我不希望DB对象发送JSON,因此在db.get_collection方法上使用try catch不是一个选项。


11
2018-02-28 11:35


起源




答案:


好吧,我不太了解Scalatra,但是 catch block是一个部分函数,​​所以你可以做这样的事情:

val errorHandling: PartialFunction[Throwable, Unit] = {
  case e:java.util.NoSuchElementException => send_error("DB malformed", InternalError)
  case e:com.mongodb.MongoException => send_error("Can not connect to MongoDB", InternalError)
  case e => send_error("Internal Error", InternalError)
}

get("/") {
  try {
   val title = db.get_collection("main", "api", "title")
   send_json(title)
  } catch errorHandling
}

6
2018-02-28 14:56



我的最终解决方案是: val errorHandling: PartialFunction[Throwable, Unit] = {  如果我使用errorHandler,我得到一个关于该名称的错误需要覆盖。它似乎也需要java.lang.Throwable而不是Exception - user1216071
@ user1216071好的,我相应地修改了代码,所以其他人不必弄明白(如果他们碰巧错过了你的评论)。 - Daniel C. Sobral


这有一个特殊的路由处理程序:

error {
  case e: Throwable => {
    redirect("/")
  }
}

通过改变 case 声明您可以打开错误类型。


39
2018-02-06 15:13



这是处理Scalatra中的错误的惯用方法,尽管文档中缺少它。 - afternoon
这应该是公认的答案。 - Andrei Taranchenko