Scala: how to avoid interlacing inside catch try blocks

I am trying to avoid variable variables, but the problem is that I have to access the val that I need to initialize inside try (this is a db operation that is executed using migth) and I need this var in the finally block

I tried several alternatives:

Val declaration inside 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 a val value outside a try block without initialization

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 var that 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 a nested try-catch block that seems pretty 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 any better approach I can take to avoid using vars and blocking try-catch nesting?

+5
source share
4 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)

fold (), Left.

+3

In the Scala block, try expression . In your case, it can evaluate a tuple containing as vals:

val res: (java.sql.ResultSet, ColumnInfo) = try {
  val rs = SQL(sql).resultSet
  (rs, ColumnInfo(rs.getMetaData))
} catch {
  case _: Throwable => throw new Exception("Error getting metadata")
} finally {
  res._1.close
}
val columnInfo = res._2
+1
source

Get rid of the first catch block:

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

All Articles