Home > Software engineering >  How to "override" an exception in scala?
How to "override" an exception in scala?

Time:05-16

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!

CodePudding user response:

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)
      }

CodePudding user response:

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).

  • Related