Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle null input parameters in Scala

Tags:

scala

I know in Scala a method should never return null... but what's about input parameters? Given the following code snippet...

object MyObject {

    def myMethod(p: String): Option[String] = {
        if (p == null) throw new IllegalArgumentException("p is null.")
        ...
    }
}

... is the way I check p correct? Is there any recommendation?

like image 240
j3d Avatar asked Nov 29 '12 22:11

j3d


2 Answers

The convention is that Scala code does not use nulls (with a tiny number of exceptions, which should immediately be fixed when using those library functions).

Thus, a null from Scala is a sign that something has gone wrong (at least a PBCAK), so you may as well throw an exception. This is not routine operation; this is something seriously screwed up. Catch the exception wherever you catch serious screw-ups. Catching an IllegalArgumentException instead of a NullPointerException adds no extra information. Just leave the original alone.

If the code comes from Java, the canonical way of dealing with it is to wrap it in Option, which will convert null to None. Then you probably don't even need to throw an exception; just return a None.

def myMethod(p: String) = Option(p).map(_.toLowerCase)

If you cannot continue when it is null, then you need to consider whether an informative exception would help. Option(p).orElse(throw new IllegalArgumentException("Null!")) is one compact way of expressing the exception-throwing sentiment.

In Scala 2.10, you can also wrap things in scala.util.Try(...) which will automatically catch and package the exception for you. If you want a packaged exception instead of a thrown one, this is the way to go. (And use Try instead of Option.)

import scala.util.Try
def myMethod(p: String) = Try(p.toLowerCase)

Finally, for more general handling of alternative outcomes, use Either. The convention for error handling is that the expected output is a Right(whatever), while Left(whatever) indicates that something went wrong.

like image 189
Rex Kerr Avatar answered Oct 25 '22 18:10

Rex Kerr


There are several ways and your way is one.

You could also use:

require(p != null, "p is null.")

or the "more functional" way would be to use Option:

def myMethod(p: String): Option[String] = {

  // no exception
  for {
    pp <- Option(p)
  } yield p + " foo bar"
}

edit:

or if you want the error without an exception thrown you can use Either:

def myMethod(p: String): Either[Exception, String] = {
  if(p == null) Left(new IllegalArgumentException("p is null."))
  else Right(p + "foo bar")
}
like image 36
drexin Avatar answered Oct 25 '22 19:10

drexin