Custom Exception in scala

前端 未结 7 832
你的背包
你的背包 2020-12-24 12:02

how can i create custom exceptions in Scala extending Exception class and throw them when exception occurs as well as catch them.

example in java :

相关标签:
7条回答
  • 2020-12-24 12:29

    Similar to other answers, but I prefer to use a companion object instead of alternate constructors.

    class MyException(message: String, cause: Throwable = null) extends Exception(message, cause)
    
    object MyException {
      def apply(message: String): MyException = new MyException(message)
      def apply(message: String, cause: Throwable): MyException = new MyException(message, cause)
    }
    
    0 讨论(0)
  • 2020-12-24 12:39

    Adding to all the answers above, If at all you want to have an error hierarchy, abstract class would help.

    abstract class GenericError(message: String) extends Exception(message)
    
    case class SpecificErrorA(message: String) extends GenericError(message)
    
    case class SpecificErrorB(message: String) extends GenericError(message)
    
    
    throw new SpecificErrorA("error on A") OR throw new SpecificErrorB("error on B")
    

    The same is possible using trait instead of an abstract class but they are limited in that they do not have constructor parameters.

    Probably use GenericError everywhere and deconstruct (pattern match) it on the application/controller boundary.

    0 讨论(0)
  • 2020-12-24 12:43
    final case class CustomException(private val message: String = "", 
                               private val cause: Throwable = None.orNull)
                          extends Exception(message, cause) 
    

    Just try catch:

    try {
        throw CustomException("optional")
    } catch {
        case c: CustomException =>
              c.printStackTrace
    }
    
    0 讨论(0)
  • 2020-12-24 12:43

    You might want to create a sealed trait:

    sealed trait MyException {
        self: Throwable => //This is called self annotations and you can use "self" or "dog" or whatever you want, it requires that those who extend this trait must also extend a Throwable or a subclass of it.
        val message: String
        val details: JsValue
    }
    

    Then you can have as many case classes as you need extending not only Exception but your new trait.

    case class CustomeException(message: String) extends Exception(message) with MyException {
        override val details: JsValue = Json.obj( "message" -> message, "etc" -> "Anything else")
    }
    

    Now, the whole point of using Scala is walking towards a more functional programming style, it will make your app more concurrent, so if you need to use your new custom exception, you might want to try something like this:

    def myExampleMethod(s: Option[String]): Future[Boolean] = {
        Try(
            s match {
                case Some(text) =>
                    text.lenght compareTo 5 match {
                        case 1 => true
                        case _ => false
                    }
                case _ => throw CustomeException("Was expecting some txt")
            }
        )
        match {
            case Success(bool) => Future.success(bool)
            case Failure(e) => Future.failed(e)
        }
    
    0 讨论(0)
  • 2020-12-24 12:48

    In order to reflect all the original constructors from Exception I'd implement a custom exception with the following pattern:

    class CustomException(msg: String) extends Exception(msg) {
      def this(msg: String, cause: Throwable) = {
        this(msg)
        initCause(cause)
      }
    
      def this(cause: Throwable) = {
        this(Option(cause).map(_.toString).orNull)
        initCause(cause)
      }
    
      def this() = {
        this(null: String)
      }
    }
    

    This can be also achieved with a trait as mentioned in previous answer. I'd just not create individual classes in this case:

    trait SomeException { self: Throwable =>
      def someDetail: SomeDetail
    }
    

    then, when throwing:

    throw new Exception(...) with SomeException {
      override val someDetail = ...
    }
    

    and when matching:

    try {
      ...
    } catch {
      case ex: Throwable with SomeException =>
        ex.getCause
        ex.getMessage
        ex.someDetail
    }
    

    The advantage here is that you are not sticking to any particular constructor of the parent exception.

    something more or less like that.

    0 讨论(0)
  • 2020-12-24 12:48

    You define your custom exception like this

    case class CustomException(s: String)  extends Exception(s)
    

    And you can throw your exception like this:

    try{
    ...
    } catch{
    case x:Exception => throw new CustomException("whatever")
    }
    
    0 讨论(0)
提交回复
热议问题