How could I initialize val object in the try catch block? - scala

I have this code in Scala, a object should be value not a variable, How can I initialize the a object in the try block?
object SomeObject {
private val a : SomeClass
try {
a=someThing // this statement may throw an exception
}
catch {
case ex: Exception=> {
ex.printStackTrace()
}
}
}

Scala tries to avoid undefined/null values. However, you can solve the problem by giving return values for the cases if the try fails and initializing a with the whole try expression:
private val a: SomeClass =
try {
someThing // this statement may throw an exception
} catch {
case ex: Exception => {
ex.printStackTrace()
someDefault
}
}
Update: In Scala it would be probably more idiomatic to use Try from scala.util:
val x : Int =
Try({
someThing
}).recoverWith({
// Just log the exception and keep it as a failure.
case (ex: Throwable) => ex.printStackTrace; Failure(ex);
}).getOrElse(1);
Try allows you to compose computations that can fail with an exception in various ways. For example, if you have two computations of type Try you can call
thing1.orElse(thing2).getOrElse(someDefault)
This runs thing1 and returns its result, if it's successful. If it fails, it continues with thing2. If it fails too, returns someDefault. You can also use recover or recoverWith to recover from some exceptions using partial functions (and potentially reuse those partial functions).

Since in Scala blocks have return values, and the last expression is the return value per default, you can do this:
object SomeObject {
private val a : SomeClass = { //this additional block not necessary, but added for clarity
try {
someThing // this statement may throw an exception
}
catch {
case ex: Exception=> {
ex.printStackTrace()
null
}
}
}
}
. However, I have to add that this looks like you're trying to accomplish something potentially blowing up in your face later - you will need null checks in any code that uses the value.

Related

How to "override" an exception in scala?

so I have a method which already has a try block that throws ExceptionA. Now I need to put another try block where this method is being called and needs to throw an exception with some added details. Something like this:
method inner():
try{
//some logic
} catch {
throw new ExceptionA("exceptionA occurred")
}
method outer():
identifier = fromSomeDBCallPrivateToOuter()
try{
inner()
} catch {
// now either
// throw new Exception("Error with identifier" + identifier)
// or
// append identifier to thrown error from inner()
}
Can someone please provide any insight or suggestion on how to do this in Scala? Thanks in advance!
What you have in your snippet would work as written (if you correct the syntax), with a caveat, that exceptions are immutable (and even they weren't, it's still not a good idea to mutate them), so, instead of "appending" to exception, you'd need to create a new one, and set the original as cause.
It is more idiomatic in scala though to use Try monad instead of the "procedural" try/catch blocks. Something like this:
case class ExceptionB(id: String, original: ExceptionA)
extends Exception(s"Badness happened with id $id", original)
def outer(): Try[ReturnType] =
val id = getId()
Try {
inner
} recover {
case e: ExceptionA if iWannaNewException => throw new Exception(s"Id: id")
case e: ExceptionA => throw ExceptionB(id, e)
}
You can also use Either structure. This structure can return Right(value) if function completes without error or Left(message) containing information about error. You can adapt your code like below one:
def inner(): Either[String, Int] = {
if (checkSomeStuff()) Left("Cannot assigne identifier")
else Right(doSomeStuff())
}
def outer(): Either[String, Int] = {
inner() match {
case Left(error) => {
println("There is an error: " + error)
// you can also throw new Exception(s"Some info about $error") here
}
case Right(identifier) => {
println("Identifier : " + identifier)
doSomeStuffWithId() // do some staff for id
}
}
}
If you want to use Exceptions you need to choose who will handle the error case (in the inner or in the outer function).

Scala "Try" return type and exception handling

I am a newbie for Scala and now am trying to complete an exercise. How can I return an InvalidCartException while the function return type is Try[Price]
//Success: return the calculated price
//Failure: InvalidCartException
def calculateCartPrice(cart:Cart): Try[Price] = {
if(isCartValid(cart)) {
//Calculations happen here
return Try(Price(totalPrice));
}
}
def isCartValid(cart: Cart): Boolean = {
//THIS WORKS FINE
}
Thank you for the help
If you mean "how to make the Try contain an exception", then use the Failure() like below:
def calculateCartPrice(cart:Cart): Try[Price] = {
if(isCartValid(cart)) {
//Calculations happen here
Success(Price(totalPrice));
} else {
Failure(new InvalidCartException())
}
}
Then, given a Try you can use getOrElse to get the value of success or throw the exception.
Try will catch the exception for you, so put the code that can throw the exception in there. For example
def divideOneBy(x: Int): Try[Int] = Try { 1 / x}
divideOneBy(0) // Failure(java.lang.ArithmeticException: / by zero)
If what you have is a Try and you want to throw the exception when you have a Failure, then you can use pattern matching to do that:
val result = divideByOne(0)
result match {
case Failure(exception) => throw exception
case Success(_) => // What happens here?
}
The Neophyte's Guide to Scala has lots of useful information for people new to Scala (I found it invaluable when I was learning).

Global try/catch implementation in scala

I am trying to look for the Global try/catch method for all my methods to handle the exception and return the same.
private def myMethod() {
try {
methodThatThrowsIOException()
} catch (IOException e) {
//What to do?
}
}
So, rather then separately calling try catch in each method , can I design a common method which will handle try/catch exception for my all other methods in scala.
here I need to make myMethod() generic and pass any methodThatThrowsIOException() .
When passing blocks to a function, especially when that function is then used all over the place with different inputs, I tend to separate it into its own parameter list:
private def myMethod[T](block: => T): Try[T] = {
Try(block())
}
This is often easier to read, e.g.:
val result = myMethod {
// your code
}
You then match on result for Failure in order to access the exception as you've asked for. If there's never a return type on methodThatThrowsIOException then you can further simplify and maybe use an Option instead of Try.
you can implement an higher order function that receives everything you'd need (sort of a template pattern). Something like this
private def myMethod[T](block: => T, errorHandling: Throwable => Any) {
Try(block()) match {
case Success(s) => s
case Failure(e) => errorHandling(e)
}
}

convert Future[MyType] into Future[Option[MyType]]

I have a Future[MyType] which is produced by an api call across the wire. If the api call fails because the wrong data was sent it just throws an Exception (not very helpful but nothing I can do about it.
So I want to check with a try / catch and return a Future[Option[MyType]] like this:
def myfunc(name:String):Future[Option[MyType]] = {
try {
val d:Future[MyType] = apiCall(name) //returns a Future[MyType]
???? Convert d into future(Some(MyType))
} catch {
future(None)
}
}
Thanks for taking a look
This really depends on where exactly the exception is being thrown. If apiCall is throwing an exception before it creates the Future, you could map the Future to wrap the value in an Option:
try {
val d: Future[Option[MyType]] = apiCall(name).map{result => Some(result)}
} catch {
case t: Throwable => Future.successful(None)
}
However I don't think this is the best way to go about this, since you are effectively losing information as to why the api call failed. Option is generally not a great solution for indicating an error has occurred. I think a better solution would be to return a future containing the exception:
try {
val d:Future[MyType] = apiCall(name)
} catch {
case t: Throwable => Future.failed(t)
}
The reason for this is whatever code you have handling the future is going to have to handle exceptions inside the future already, so this will keep all your error handling in one place.
If the exception is being thrown inside the Future, wrapping apiCall in a try/catch block won't help since the exception is not thrown synchronously, so you can use map and recover:
val d: Future[Option[MyType]] = apiCall(name).map{Some(_)}.recover{
case t: Throwable => None
}

try block scope

I'm unhappy with the rule about variable scope in a try block not being shared with associated catch and finally blocks. Specifically it leads to code like the following:
var v: VType = null
try {
v = new VType()
}
catch {
case e => // handle VType constructor failure (can reference v)
}
finally {
// can reference v.
}
As opposed to:
try {
val v = new VType()
}
catch {
case e => // handle VType constructor failure (can reference v)
}
finally {
// can reference v.
}
Can anyone please explain or justify why this rule from Java persists?
and / or is there hope that this could change?
Thanks!
UPDATE
Many thanks for all the responses to date.
The consensus seems to imply "just get on with it" and I'm starting to conclude that perhaps technically what I want is either unsound, not worth the effort or hard to achieve.
I like Rex Kerr's answer but how would the original code above be wrapped in a method call without introducing a local var in the method body?
My own efforts weren't too good, using a by-name parameter to delay construction until safely in the try block works but still doesn't give me access to the constructed (or not) object in the catch or finally blocks.
Just "try" this ;)
val v = try { new VType() } catch { case e: Exception => /* ... */ }
In Scala, try is an expression, so it has a value.
You might be thinking about the problem the wrong way. Why do you want so much stuff in your try/catch/finally block? In your code,
try { val v = new VType() }
the exception could be thrown before you get v back, so you can't safely reference v. But if you can't reference v, then what can you do on the finally side that won't break or throw its own exception or have some other ill-defined behavior? What if you create v but fail to create w, but disposal requires having w as well? (Or doesn't?) It ends up being a mess.
But if you're coming from Java, there are a few things that can help you write try/catch/finally blocks in a sensible way.
One thing you can do is catch certain classes of exceptions and turn them into options instead:
def s2a(s: String) = try { Some(s.toInt) } catch { case nfe: NumberFormatException => None}
Another thing you can do is to create your own resource manager
def enclosed[C <: { def close() }](c: C)(f: C => Unit) {
try { f(c) } finally { c.close() }
}
enclosed(new FileInputStream(myFile))(fis => {
fis.read...
}
Or you can create your own shut-down-and-escape-safely method within another method:
val r = valuableOpenResource()
def attempt[F](f: => F) = {
try { f } catch { case re: ReasonableException => r.close() throw re }
}
doSomethingSafe()
attempt( doSomethingDangerous() )
doSomethingElseSafe()
r.close()
Between these different ways of handling things, I've not had much need to create vars to hold variables that I want to clean up later or otherwise deal with in catch or finally blocks.
How would this code work?
try
{
int i = 0;
// Do stuff...
Foo x = new Foo();
// Do more stuff...
Bar y = new Bar();
}
catch
{
// Print the values of i, x, and y.
}
What are the values of i, x, and y? Did y even get declared before we landed in the catch block?
The exception concept is not a subroutine of the try block, it is an alternate code flow. That makes at try-catch control block more like an "if anything untoward happens" then insert these (catch) lines in the current position of the try block, as needed.
With that in mind, it isn't clear if Val v = Type(); is going to be defined or not because the exception could (theoretically) be thrown before Val v = Type(); is evaluated. Yes, Val v is the first line in the block, but there are JVM errors which could be thrown before it.
Finally is another code construct which adds and alternate, but required, code flow the end of leaving the try-catch construct. Again, we have no idea how much (if any) of the try block was evaluated before the finally block was called, so we cannot depend on the declared variables within that block.
The only alternative left (now that we cannot use try block variables, due to their uncertainty of existence) is to use variable outside of the entire try-catch-finally construct for communications between the individual code blocks.
Does it suck? Maybe a little. Do we have anything that's better? Probably not. Putting the variable declarations outside of the block makes it obvious that the variables will have been defined prior to whatever control structure you process through in a try-catch-finally scenario.
If your main concern is that v should be immutable, you might get close to what you want with:
case class VType(name: String) {
// ... maybe throw an exception ...
}
val v = LazyVal(() => new VType())
try {
// do stuff with v
println(v.name) // implicitly converts LazyVal[VType] to VType
// do other unsafe stuff
} catch {
case e => // handle VType constructor failure
// can reference v after verifying v.isInitialized
} finally {
// can reference v after verifying v.isInitialized
if (v.isInitialized) v.safelyReleaseResources
}
where LazyVal is defined as
/**
* Based on DelayedLazyVal in the standard library
*/
class LazyVal[T](f: () => T) {
#volatile private[this] var _inited = false
private[this] lazy val complete = {
val v = f()
_inited = true
v
}
/** Whether the computation is complete.
*
* #return true if the computation is complete.
*/
def isInitialized = _inited
/** The result of f().
*
* #return the result
*/
def apply(): T = complete
}
object LazyVal {
def apply[T](f: () => T) = new LazyVal(f)
implicit def lazyval2val[T](l: LazyVal[T]): T = l()
}
It would be nice if we could use lazy val v = new VType(), but AFAIK there is no mechanism to safely determine whether a lazy val has been initialized.
Here's another alternative:
object Guard {
type Closing = {def close:Unit}
var guarded: Stack[Set[Closing]] = Stack()
def unapply(c: Closing) = {
guarded.push(guarded.pop + c)
Some(c)
}
private def close {println("Closing"); guarded.head.foreach{c => c.close}}
private def down {println("Adding Set"); guarded.push(Set())}
private def up {println("Removing Set"); guarded.pop}
def carefully(f: => Unit) {
down
try {f}
finally {close; up}
}
}
You can use it like this:
import Guard.carefully
class File {def close {println("Closed File")}}
class BadFile {def close {println("Closed Bad File")}; throw new Exception("BadFile failed")}
carefully {
val Guard(f) = new File
val Guard(g) = new File
val Guard(h) = new BadFile
}
which results in
Adding Set
Closing
Closed File
Closed File
java.lang.Exception: BadFile failed
So the first two files are created, then when the third constructor fails, the first two are automatically closed. All files are values.
Your example does not concretize why you need the finally clause. If VType is e.g. a resource that needs do be closed, you could do it one of the following ways.
1) You want to reference v after using it throws an exception:
try {
val v = new VType // may throw
try {
v.someThing // may throw
}
catch {
case ex => println("Error on doing something with v :" + v + ex) // or whatever
}
finally {
v.close()
}
}
catch {
case ex => println("Error on getting or closing v: " + ex) // v might not be constructed
}
2) You don't care about v in the catch clause:
try {
val v = new VType // may throw
try {
v.someThing // may throw
}
finally {
v.close()
}
}
catch {
case ex => println("Error on either operation: " + ex)
}
In either case, you get rid of the var.