2
\$\begingroup\$

This is code that handles pushing data to an analytics API, and IMO it feels too much like Java.

logActivity is a method that uses Dispatch to POST the data to this API. I am worried that an exception could occur and that is why I wrapped the methods in a try/catch block. However, this feels very Javaesque.

Do I even need the try/catch block? Can logActivity method fail and cause the end point to stop working? Any better ways to do this?

  def buyLinkAnalytics(notif: Notification, reqInfo: RequestInfo): Unit = {
    try {
      logActivity(buy_link_requested, Some(LoggedInAccount(AccountId(notif.emails.get.to._id))), notif.productId.get._id.toString, None, reqInfo)
    } catch {
      case e: Exception => {
        log.error(e.toString)
      }
    }
}

  def productShareAnalytics(notif:Notification, reqInfo:RequestInfo): Unit = {
    try {
      logActivity(product_shared, Some(LoggedInAccount(AccountId(notif.emails.get.to._id))), notif.productId.get._id.toString, None, reqInfo)
    } catch {
      case e: Exception => {
        log.error(e.toString)
      }
    }
  }

  def welcomeAnalytics(notif:Notification, reqInfo:RequestInfo): Unit = {
    val uri = reqInfo.stripedUri
    try {
      logActivity(welcome, Some(LoggedInAccount(notif.accounts.get.from.get)), uri, None, reqInfo)
    } catch {
      case e: Exception => {
        log.error(e.toString)
      }
    }
  }

  def myCatalogAnalytics(notif:Notification, reqInfo:RequestInfo): Unit = {
    val uri = reqInfo.stripedUri
    try {
      logActivity(welcome, Some(LoggedInAccount(notif.accounts.get.from.get)), uri, None, reqInfo)
    } catch {
      case e: Exception => {
        log.error(e.toString)
      }
    }
  }



  def handleAnalytics(notif:Notification, reqInfo:RequestInfo) {
    notif.notification match {
      case BuyProduct => buyLinkAnalytics(notif, reqInfo)
      case ProductShare => productShareAnalytics(notif, reqInfo)
      case Welcome => welcomeAnalytics(notif, reqInfo)
      case MyCatalog => myCatalogAnalytics(notif, reqInfo)
      case _ => log.debug("Notification Type not found. Nothing put into analytics")
    }
  }


  def sendActivityLog[A] (account_id: String, activityLog: A, authParams: Map[String, String] = Map.empty[String, String], endpoint: String)(implicit fmt: Format[A]) = {
    val activityLogJson = Json.stringify (Json.toJson (activityLog))
    val scv = url(s"${config.getString("activity_log.url")}$endpoint/$account_id?key=wc_analytics") << activityLogJson <:< Map("Content-Type" -> "application/json") <:< authParams
    logger.debug(s"LOGGED: ${scv.url} << $activityLogJson")
    Http (scv OK as.String)
  }



  def logActivity (
    action      : String,
    visitor     : Option[Visitor],
    uri         : String,
    target_id   : Option[String],
    requestInfo : RequestInfo,
    context     : String = "-") = {
    import core.security.AppId.WcApp
    // In theory, no loggable business event should ever occur without an AppId.
    // But default to WC if we have to.

    val appId = requestInfo.appId.getOrElse (WcApp)._id


      val authParams = findAuthParams(requestInfo)

    if (visitor == None) {
      sendActivityLog ("None", ActivityLog (appId, action, uri, "-", context), authParams, activity_account)
    }
      visitor.foreach {
        case LoggedInAccountWithOther (account_id, other_id) =>
          sendActivityLog (
            account_id._id,
            ActivityLog (
              appId,
              action,
              uri,
              target_id.getOrElse (other_id._id),
              context
            ),
            authParams,
            activity_account
          )
        case v =>
          sendActivityLog (v.accountId._id, ActivityLog (appId, action, uri, "-", context), authParams, activity_account)
      }

  }
\$\endgroup\$
2
\$\begingroup\$

If you think that those try/catch blocks look too verbose, then you can create utility method like:

def logExceptions[R](body: => R): R =
  try { body }
  catch {
    case e: Exception => log.error(e.toString)
  }

Then rewrite your code like:

def buyLinkAnalytics(notif: Notification, reqInfo: RequestInfo) {
  logExceptions {
    logActivity(buy_link_requested, Some(LoggedInAccount(AccountId(notif.emails.get.to._id))), notif.productId.get._id.toString, None, reqInfo)
  }
}

def productShareAnalytics(notif:Notification, reqInfo:RequestInfo) {
  logExceptions {
    logActivity(product_shared, Some(LoggedInAccount(AccountId(notif.emails.get.to._id))), notif.productId.get._id.toString, None, reqInfo)
  }
}

...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.