1

I would like to have some suggestions on exception handling mechanism. I currently have the traditional try catch finally but I understand that it is not functional in style. So what is the best functional way of handling exceptions. I tried looking into the Scala arm, but it is just a functional wrapper around the try catch finally I suppose! Suggestions? Here is my Play controller where I want to handle the exception that is thrown and send a plain String back to the client!

def testmethod = Action(parse.maxLength(10 * 1024 * 1024, parser = parse.anyContent)) { implicit request =>
    request.body match {
      case Left(_) => EntityTooLarge
      case Right(body) => {
        println(request.headers.toSimpleMap)
        val js = // Get the value from the request!!!

        val resultJsonfut = scala.concurrent.Future { longRunningProcess(js) }

        Async {
          if(request.headers.toSimpleMap.exists(_ == (ACCEPT_ENCODING, "gzip"))) {
            resultJsonfut.map(s => {
              val bytePayload = getBytePayload(s) // How to handle exceptions thrown by getBytePayLoad????
              Ok(bytePayload)
            })
          } else {
            resultJsonfut.map(s => Ok(s))
          }
        }
      }
    }
  }
joesan
  • 13,963
  • 27
  • 95
  • 232

1 Answers1

2

You could create a method that you would call to handle exception inside your Actions, this method would look something like this:

def withExceptionHandling(f: => Result)(implicit request: Request[AnyContent]): Result = 
    try{ f }catch{ case e: Exception => InternalServerError("Something bad happened")}

And then you would use it like this:

def testmethod = Action(parse.maxLength(10 * 1024 * 1024, parser = parse.anyContent)) { implicit request => 
  withExceptionHandling {
    request.body match {
      case Left(_) => EntityTooLarge
      case Right(body) => {
        println(request.headers.toSimpleMap)
        val js = // Get the value from the request!!!

        val resultJsonfut = scala.concurrent.Future { longRunningProcess(js) }

        Async {
          if(request.headers.toSimpleMap.exists(_ == (ACCEPT_ENCODING, "gzip"))) {
            resultJsonfut.map(s => {
              val bytePayload = getBytePayload(s) // How to handle exceptions thrown by getBytePayLoad????
              Ok(bytePayload)
            })
          } else {
            resultJsonfut.map(s => Ok(s))
          }
        }
      }
    }
  }
}

This will prevent you from explicitly trying and catching on each of your Actions.

Peter
  • 7,020
  • 4
  • 31
  • 51
  • That sounds like an idea. But how do you handle closing of streams that we normally do in the finally block? – joesan Feb 25 '14 at 13:37
  • Check this question, seems it handles exactly what you needs in terms of closing streams/releasing resources... http://stackoverflow.com/questions/8865754/scala-finally-block-closing-flushing-resource – Peter Feb 25 '14 at 13:49