在Play框架中使用带Websocket的Try / Catch时出错

时间:2015-10-07 10:00:33

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

我在Scala中使用带有Play Framework的Web套接字。我想在我的项目中使用Try/Catch功能来捕获ExceptionsServer ExceptionNetwork Exception等。{/ p>

我做了什么:

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功能

1 个答案:

答案 0 :(得分: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?