Monday, June 22, 2009

Catching Exceptions

A fellow blogger was complaining about Google Code returning an exception instead of null, which made his code look ugly. Not so, says I! Scala (and monads, I suppose) come to rescue:


def exceptionToLeft[T](f: => T): Either[java.lang.Throwable, T] = try {
Right(f)
} catch {
case ex => Left(ex)
}


exceptionToLeft(obj.methodWhichMightThrow()) match {
case Right(x) => // do stuff with x
case Left(ex) => println("Oops, got exception " + ex.toString)
}


Enjoy!

Update:

Scala 2.8 has library help for this, at scala.util.control.Exception. It does require one to specify the exception or exceptions to be caught, which is a good thing, and it has many more usage modes. You can just ignore the exception for computations returning Unit, you can get the result as Some(T) and transform the exceptions in None, etc.

3 comments:

  1. Nice. One note; the Scaladocs for Either say that the convention is to use Left for the exception case, when an Either is used for success vs. failure scenarios like this.

    ReplyDelete
  2. Yeah, I know it. But I was concentrating on capturing the exception, so I used Right in my test code. Once it was finished, I was unwilling to swap Left and Right for fear of breaking something.

    Alas, though I have heard Either described as a way to pass two alternative type values -- something like we would "union" for in C -- it seems the original intent of Either was, indeed, handling exceptions.

    I guess I might as well fix the code before people start copying it.

    ReplyDelete
  3. Hopefully people won't start copying it because it's already in trunk in a more general form. See scala.util.control.Exception.

    ReplyDelete