5

I'm trying to find the simplest yet proper way to extend a Java Exception in Scala. For example, the following is not correct because new Exception(null, cause) and new Exception(cause) have different behavior according to Throwable.java:

class InvalidVersionException(message: String = null, cause: Throwable = null)
  extends IllegalArgumentException(message, cause) {
  def this(message: String) = this(message, null)
  // This is not same with super(cause)
  def this(cause: Throwable) = this(null, cause)
}

Because I know Throwable(cause) sets the message to cause.toString(), I came up with the following:

class InvalidVersionException(message: String = null, cause: Throwable = null)
  extends IllegalArgumentException(if ((message eq null) && (cause ne null)) cause.toString else message, cause) {
  def this(message: String) = this(message, null)
  def this(cause: Throwable) = this(null, cause)
}

However, this still has:

if ((message eq null) && (cause ne null)) cause.toString

which was duplicated from Throwable.java.

Is there a better way to extend an Exception without any code duplication?

trustin
  • 12,231
  • 6
  • 42
  • 52

3 Answers3

2

It looks to me like you should be able to just change the cause-only constructor to:

def this(cause: Throwable) = this(cause.toString, cause)

EDIT: To handle null cause:

def this(cause: Throwable) = this(if (cause == null) "(no message)" else cause.toString, cause)

Replace "(no message)" with null (not recommended) or whatever text you feel is appropriate.

Shadowlands
  • 14,994
  • 4
  • 45
  • 43
0

How about this?

trait InvalidVersionException extends IllegalArgumentException

object InvalidVersionException {
  def apply(msg: String) = new IllegalArgumentException(msg) with InvalidVersionException
  def apply(cause: Throwable) = new IllegalArgumentException(cause) with InvalidVersionException
  def apply(msg: String, cause: Throwable) = new IllegalArgumentException(msg, cause) with InvalidVersionException
}

(via "In Scala, how can I subclass a Java class with multiple constructors?")

Community
  • 1
  • 1
Henning
  • 11,496
  • 5
  • 27
  • 25
  • I'm unsure if it's a good idea to make an exception a trait. Doesn't it really mean any random class can extend it? – trustin Aug 23 '13 at 10:11
0

Based on the answer by @Shadowlands, I ended up with the following:

class InvalidVersionException(message: String, cause: Throwable = null)
  extends IllegalArgumentException(message, cause) {
  def this(cause: Throwable) = this(if (cause ne null) cause.toString else null, cause)
  def this() = this(null)
}

.. which saves 54 bytes.

trustin
  • 12,231
  • 6
  • 42
  • 52