如何捕获Scalatra操作中的所有错误?

13

我正在使用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会让代码变得很丑陋,有没有什么方法可以避免或减少这种情况?我是Scala(和Java)的新手,可能还有些东西不太懂。

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

2个回答

46

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

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

通过更改 case 语句,您可以针对错误类型进行切换。


1
这是在Scalatra中处理错误的惯用方法,尽管它在文档中缺失。 - afternoon

6

我对Scalatra的了解不足,但 catch 块是一个偏函数,所以你可以像这样做:

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
}

我的最终解决方案是: val errorHandling: PartialFunction[Throwable, Unit] = {如果我使用errorHandler,会出现关于需要覆盖该名称的错误。 它似乎还需要java.lang.Throwable而不是Exception。 - user1216071
@user1216071好的,我已经相应地修复了代码,这样其他人就不必自己去琢磨了(如果他们错过了你的评论)。 - Daniel C. Sobral

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接