我正在使用Scala和Play进行微服务。它有一个Controller,它使用Action.async构造和自定义主体解析器。这是一个示例代码:
def crud(param: String) = Action.async(SomeCustomBodyParser) { implicit request =>
try {
<some code>
} catch {
case _ => <Exception Handling logic>
}
}
此代码的问题是,如果SomeCustomBodyParser
中出现异常,则不会在catch块中处理它。我尝试了一些方法,我在外面提取它,然后手动处理它,但异常未正确捕获。 Action.async的代码表明它需要一段代码并将其作为一个单独的上下文执行。我不清楚它究竟是如何运作的。
如何处理异常并吐出更好的异常消息。
答案 0 :(得分:1)
必须为$sql = "SELECT * from locations";
$query_args = array(
);
try {
$stmt = $db->prepare($sql);
$result = $stmt->execute($query_args);
} catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Database Error2. Please Try Again!";
$response["details"] = $ex;
}
$result = $stmt->fetchAll();
echo json_encode($result);
提供Action.async
,这可以通过成功Future[Result]
或失败来完成。
任何Result
failed
都会导致HTTP响应错误。
Future
格式化这种错误的方式可以是cistomized。
答案 1 :(得分:1)
此处的问题是您尝试使用同步错误处理程序来处理异步错误。 try catch
只能处理同步错误。 Future[_]
本质上是异步的,如果有try catch
语句已经执行(并且可能在不同的线程中),它将抛出错误。
相反,在scala中,我们通过使用scalaz中的Option
或Either
或\/
等数据结构来明确错误处理。所有这些包装形成Monad。
在大多数异步服务器设置中,你想要的是Future
里面有Either
(或者来自scalaz的右偏差变体,如\/
。)这样,你就可以抽象出异步性和错误处理。由于两个包装器都是monad,您可以使用 Monad Transformers 组合它们。这是一个很深刻的话题,如果您不熟悉它,需要相当多的学习,但这种数据结构的要点如下:
class Task[E, A] {
def flatMap[U](f: A => Task[E, U]): Task[E, U] = ??? // Use monad transformer here.
}
其中E
表示自定义错误的类型 - 您可能会通过sealed trait
等代数数据类型来表示它们,其中包含大量case class
而A
是您的值类型
答案 2 :(得分:0)
如果您的BodyParser抛出异常,或由于某些其他原因而失败,那么Action中的任何代码都将无法执行。 async
的性质与此无关。
例如,以下代码中的System.exit
永远不会运行,因为BodyParser 始终会返回异常。
package controllers
import javax.inject.Inject
import play.api.mvc._
import scala.concurrent.Future
class Application @Inject() extends Controller {
def crud(param: String) = Action.async(
parse.error[String](Future.failed(new RuntimeException("oh noes!")))
) { req =>
System.exit(0)
???
}
}
此代码生成此堆栈跟踪:
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[RuntimeException: oh noes!]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:254) ~[play_2.11-2.4.0.jar:2.4.0]
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:180) ~[play_2.11-2.4.0.jar:2.4.0]
堆栈跟踪表示有一个DefaultHttpErrorHandler
被调用,并且从BodyParser抛出异常。
ScalaErrorHandling的文档包含自定义此内容或编写自己的文档的示例。