Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala: how to avoid mutables inside try catch blocks

I'm trying to avoid mutables variables, but the problem is that I have to access a val that I need to initialize inside the try (it's a db operation that migth fail) and I need that var in the finally block

I tried with several alternatives:

declaring the val inside the try block

try {
  val resultSet = SQL(sql).resultSet
  return ColumnInfo(resultSet.getMetaData)
} catch {
  case e => throw new ColumnInfoException("Error getting metadata")
} finally {
  resultSet.close
}

error: not found: value resultSet

declaring the val outside the try block without initializing it

val resultSet: java.sql.ResultSet
try {
  resultSet = SQL(sql).resultSet
  return ColumnInfo(resultSet.getMetaData)
} catch {
  case e => throw new ColumnInfoException("Error getting metadata")
} finally {
  resultSet.close
}

error: only classes can have declared but undefined members

using a var, which seems to work

var resultSet: java.sql.ResultSet = null
try {
  resultSet = SQL(sql).resultSet
  return ColumnInfo(resultSet.getMetaData)
} catch {
  case e => throw new ColumnInfoException("Error getting metadata")
} finally {
  resultSet.close
}

and finally nesting try-catch block, which seems rather dirty

try {
  val resultSet = SQL(sql).resultSet
  try {
    return ColumnInfo(resultSet.getMetaData)
  } catch {
    case e => throw new ColumnInfoException("Error getting metadata")
  } finally {
    resultSet.close
  }
} catch {
  case e => throw new ColumnInfoException("Error opening resultSet")
}

Is there some better approach I can take to avoid using vars and nesting try-catch blocks?

like image 996
opensas Avatar asked Sep 11 '12 04:09

opensas


2 Answers

import scala.util.control.Exception._

allCatch.either(SQL(sql).resultSet).right.flatMap{ resultSet =>
  val ans = allCatch.either(ColumnInfo(resultSet.getMetaData))
  resultSet.close
  ans
}.fold(e => throw e, identity)

or you can skip the fold and keep the exception(s) packaged in Left.

like image 176
Rex Kerr Avatar answered Oct 06 '22 08:10

Rex Kerr


from this question functional try & catch w/ Scala

I learned about the loan pattern: https://wiki.scala-lang.org/display/SYGN/Loan

Play framework itself seems to use it with the DB.withConnection method

like image 39
opensas Avatar answered Oct 06 '22 08:10

opensas