Question: In java exceptions have at least these four constructors:

```
Exception() 
Exception(String message) 
Exception(String message, Throwable cause) 
Exception(Throwable cause) 

```

If you want to define your own extensions, you just have to declare a descendent exceptions and implement each desired constructor calling the corresponden super constructor

How can you achieve the same thing in scala?

so far now I saw [this article](https://lizdouglass.wordpress.com/2010/12/15/scala-multiple-constructors/) and this [SO answer](https://stackoverflow.com/a/3300046/47633), but I suspect there must be an easier way to achieve such a common thing

Answer: 
Default value for `cause` is null. And for `message` it is either `cause.toString()` or null:

```
val e1 = new RuntimeException()

e.getCause
// res1: java.lang.Throwable = null

e.getMessage
//res2: java.lang.String = null

val cause = new RuntimeException("cause msg")
val e2 = new RuntimeException(cause)

e.getMessage()
//res3: String = java.lang.RuntimeException: cause msg

```

So you can just use default values:

```
class MyException(message: String = null, cause: Throwable = null) extends
  RuntimeException(MyException.defaultMessage(message, cause), cause)

object MyException {
  def defaultMessage(message: String, cause: Throwable) =
    if (message != null) message
    else if (cause != null) cause.toString()
    else null
}

// usage:
new MyException(cause = myCause)
// res0: MyException = MyException: java.lang.RuntimeException: myCause msg

```
Scala pattern matching in try/catch blocks works on interfaces. My solution is to use an interface for the exception name then use separate class instances.

```
trait MyException extends RuntimeException

class MyExceptionEmpty() extends RuntimeException with MyException

class MyExceptionStr(msg: String) extends RuntimeException(msg) with MyException

class MyExceptionEx(t: Throwable) extends RuntimeException(t) with MyException

object MyException {
  def apply(): MyException = new MyExceptionEmpty()
  def apply(msg: String): MyException = new MyExceptionStr(msg)
  def apply(t: Throwable): MyException = new MyExceptionEx(t)
}

class MyClass {
  try {
    throw MyException("oops")
  } catch {
    case e: MyException => println(e.getMessage)
    case _: Throwable => println("nope")
  }
}

```

Instantiating MyClass will output "oops".