【问题标题】:Error when using Try/Catch in Play Framework with Websocket在带有 Websocket 的 Play Framework 中使用 Try/Catch 时出错
【发布时间】:2015-10-07 10:00:33
【问题描述】:

我在 Scala 中使用带有 Play Framework 的 Web 套接字。我想在我的项目中使用Try/Catch 功能来捕获一些Exceptions,例如Server ExceptionNetwork Exception 等。

我做了什么:

WebSocketController.scala

object LoginWS {
  def props(out: ActorRef) = Props(new LoginWS(out))
}

class LoginWS(out: ActorRef) extends Actor {
  def receive = { 
    case json_req: JsObject =>
      var user_name = (json_req \ "user_name").as[String]
      var password = (json_req \ "password").as[String]
      var source = (json_req \ "source_type").as[String]
      var result = UserLogin.authenticateUser(user_name, password).isDefined
      var userID: Int = 0;
      if(result) {
        userID = UserLogin.getUserRole(user_name, password)
        val login_status : String = "Success"            
        out ! Json.toJson(JsObject(Seq("login_status" -> JsString(login_status), "user_id" -> JsNumber(userID))))
      }
      else {
        val login_status : String = "Failure"
        out ! Json.toJson(JsObject(Seq("login_status" -> JsString(login_status), "user_id" -> JsNumber(userID))))
      }
  }      
}  

object WebSocketController extends Controller {            
  def login = WebSocket.acceptWithActor[JsValue, JsValue] { request => 
    out => LoginWS.props(out)
  }   
}

我尝试了什么:

我使用了this answer posted by Ende Neu,但它显示not found: value APIAction。注意:我也在 routes 文件中添加了 APIAction

代码:

class LoginWS(out: ActorRef) extends Actor {
  def receive = APIAction { request
    case json_req: JsObject =>
     .....
     ....//code here
  }

}
object WebSocketController extends Controller {

  def login = WebSocket.acceptWithActor[JsValue, JsValue] { request =>
    out => LoginWS.props(out)
  } 

  def APIAction(f: Request[AnyContent] => Result): Action[AnyContent] = 
    Action { request =>
      Try(f(request))
        .getOrElse(
          InternalServerError(Json.obj("code" -> "500", "message" -> "Server error"))
        )
    }    
}

请帮助我在Web socket 中实现 Try/Catch 功能

【问题讨论】:

  • 动作在控制器内部使用,而不是演员,演员只会处理消息,接收必须是部分函数,​​而不是动作
  • 那么我该如何处理error operations in Action login 正如你所说的

标签: scala playframework websocket try-catch playframework-2.3


【解决方案1】:

登录请求在actor内部处理,我认为你应该在那里处理你的错误。如果您想捕获所有异常而不是明确处理可能出现的问题,我建议您执行以下操作

object SomeUtils {
  def catchAll[A](out: ActorRef)(f: => A): Unit = {
    val message = Try(f).getOrElse(Json.obj("code" -> "500", "message" -> "Server error"))
    out ! message
  }
}


import SomeUtils._

class LoginWS(out: ActorRef) extends Actor {
  def receive = {
    case json_req: JsObject => catchAll(out) {
      val userName = (json_req \ "user_name").as[String]
      val password = (json_req \ "password").as[String]
      val authenticated = UserLogin.authenticateUser(userName, password).isDefined
      if (authenticated) {
        val role = UserLogin.getUserRole(userName, password)
        Json.obj("login_status" -> "Success", "result" -> role)
      }
      else {
        Json.obj("login_status" -> "Failure", "result" -> 0)
      }
    }
  }
}

在处理jsonReq 时,使用catchAll 方法会期望获得结果的接收者,而这个结果可能会抛出Exception。如果是Exception,它将使用带有内部服务器错误的默认消息,并将此消息发送给接收者。

您还可以将 out 参数设为隐式,以跳过将其放在任何地方。此外,您的代码也不是真正的 scala 风格。使用vars 等...

如果发送到 WS 的 json 无法解析,它会在到达您的代码之前抛出异常,可以在此处找到解决方案:

How do I catch json parse error when using acceptWithActor?

【讨论】:

  • 我会检查并通知您。
  • 我用我的代码修改了你的更改它没有显示任何错误但是如果我在请求中发送值它不会发送任何响应消息。在包含你的代码之前它显示响应为{ "login_status":"Success","user_id":21}
  • 我改变了答案,因为我注意到 WebSockets 不返回 Result 但在你的情况下是 JsValue。
  • 我更新了您的更改,但现在它总是返回错误RESPONSE: {"code":"500","message":"Server error"},即使我们发送了正确的请求。
  • 好吧,我不确定可能是什么原因。也许我错过了一些东西。也许我毁了你的代码,也许把你的版本放回catchAll。也许在执行过程中会抛出异常,如果是这样,您可以通过将 catchAll 实现替换为 val message = try f catch { case NonFatal(e) => Json.obj("code" -> "500", "message" -> s"${e.getClass.toString}: ${e.getMessage}") }; out ! message 来检查会发生什么
猜你喜欢
  • 2014-06-10
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多