Saturday, August 9, 2014

Preventing NPE when creation Option

Sometimes you don't know whether values are present and you want to use an Option to represent that posibility. While Scala API's often support returning an Option, this is not so when integrating with Java. You might want to get a value somewhere from an object hierarchy like this:
user.getAddress().getStreet()
Since you might expect a value is not present, you want to wrap this in an Option. However, if either 'user' or 'address' is null, Option will throw a NPE.

To guard against this, you want to catch any NPE and return a normal None. However, the Option trait is sealed so it is not possible to extend it. Here is a solution how it can be done by using an object with an 'apply' method. This SafeOption returns a normal Option (Some or None), but catches any NPE and returns a None in that case.
/**
 * A 'safe' type of Option which catches any exception, so also NPE's
 * when creating the option.
 * So 'SafeOption(null.name)' will return None.
 */
object SafeOption {

  def apply[A](value: => A): Option[A] = try {
    Option(value)
  } catch {
    case _: NullPointerException => None
  }
}
Use the SafeOption like this, not much different from creating a normal Option:
SafeOption(user.getAddress().getStreet())
Note: use this only in case when you don't care about the null's and a None is a valid option for you in those cases.

Another note: It would be possible for SafeOption to catch any kind of Exception or Throwable instead of only a NullPointerException, but this would totally depend on you application whether that is a valid solution or not. I just choose to only catch NullPointerException so other kinds of exceptions can still be handled differently by the application.

Happy Optioning ;-)