14

I have the following code:

try {
    < ... some JSON parsing code .. >
} 
catch {
    case e:ClassCastException => throw new ParseException(body, e)
    case e:JSONException => throw new ParseException(body, e)
}

This seems overly repetitious. I tried

case e:ClassCastException | e:JSONException => throw new ParseException(body, e)

but Scala won't let me bind e to both types - fair enough. In the handler, I only need to treat e as if it were of type Exception, but I only want to match in the first place if it's one of those specific classes. Something like having a condition after the matched type, like:

case e:Exception(ClassCastException|JSONException) => throw new ParseException(body, e)

That's obviously not the right syntax, but hopefully you see what I mean. Is such a thing possible?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
gfxmonk
  • 8,614
  • 5
  • 42
  • 53

2 Answers2

24

You can't introduce bindings inside of Pattern Alternatives (PatternA | PatternB). But you can bind a name to the result of Pattern Alternatives with a Pattern Binder (name @ Pattern).

try {
    < ... some JSON parsing code .. >
} catch {
    case e @ (_: ClassCastException | _: JSONException) => throw new ParseException(body, e)
}
retronym
  • 54,768
  • 12
  • 155
  • 168
8

You could use the new 2.8 control constructs:

def foo = //JSON parsing code

import util.control.Exception._
handling(classOf[ClassCastException], classOf[JSONException]) by (t => throw new ParseException(t)) apply foo

(There's probably a mistake in there. I can't find an REPL for the jabscreen.)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449