All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.reactific.helpers.ThrowingHelper.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015-2017 Reactific Software LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.reactific.helpers

trait ThrowableWithComponent extends Throwable {
  protected def component: LoggingHelper

  override def getStackTrace: Array[StackTraceElement] = {
    val st = super.getStackTrace
    if (st != null && st.nonEmpty) {
      st.dropWhile { ste: StackTraceElement =>
        ste.getClassName.startsWith("com.reactific.helpers.ThrowingHelper.")
      }
    } else {
      st
    }
  }

  def getLocation: String = {
    val st = getStackTrace
    if (st != null && st.nonEmpty) {
      val ste = getStackTrace.head
      val simpleClassName = ste.getClassName.indexOf('$') match {
        case -1 ⇒
          ste.getClassName
        case dollar: Int ⇒
          ste.getClassName.take(dollar)
      }
      s"$simpleClassName:${ste.getFileName}:${ste.getLineNumber}"
    } else {
      s"NoStack"
    }
  }

  override def getMessage: String = {
    s"${getClass.getName}: ${super.getMessage} @${
      component.loggerName}:$getLocation"
  }
}

/** Assistance With Throwing Exceptions
 * Uses LoggingHelper base class to throw an error message that
 * identifies the thrower.
 */
trait ThrowingHelper extends LoggingHelper {
  protected def mkThrowable(
    msg: String,
    cause: Option[Throwable] = None
  ): ThrowableWithComponent = {
    new TossedException(this, msg, cause.orNull)
  }

  def notImplemented(what: String): Nothing = {
    throw new NotImplementedException(this, what) {}
  }

  /** Identity Aware Exception Toss
   * This function makes it easier to throw (toss) an exception that adds a
   * message to it and also identifies the tosser that threw it. This helps
   * track down where in the code the message was thrown from.
   *
   * @param msg - Message to add to the exception
   * @param cause - The root cause exception
   */
  def toss(msg: ⇒ String, cause: Option[Throwable] = None): Nothing = {
    throw mkThrowable(msg, cause)
  }
}

class TossedException(
  val component: LoggingHelper,
  val message: String,
  val cause: Throwable)
    extends java.lang.Exception(message, cause) with ThrowableWithComponent

object TossedException {

  def apply(
    component: LoggingHelper,
    message: String,
    cause: Throwable
  ): TossedException = {
    new TossedException(component, message, cause)
  }

  def apply(component: LoggingHelper, message: String): TossedException = {
    new TossedException(component, message, None.orNull)
  }
}

class NotImplementedException(component: LoggingHelper, what: String)
    extends TossedException(component, s"Not Implemented: $what", None.orNull)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy