2
votes

The following method uses a future to send email and then catches any exception mail.send might throw:

sendEmail(from: String, recipients: Seq[String],
  subject: String, body: (Option[Txt], Option[Html])) = Try {

  import com.typesafe.plugin._
  import scala.concurrent.future
  import play.api.libs.concurrent.Execution.Implicits.defaultContext

  val mail = use[MailerPlugin].email

  mail.addFrom(from)
  recipients.map(mail.addRecipient(_))
  subject.map(mail.setSubject(subject)

  future {
    try {
      mail.send(body._1.map(_.body).getOrElse(""), body._2.map(_.body).getOrElse(""))
    } catch {
      case NonFatal(e) => Logger.warn("[%s] error sending email".format(ClassName, subject), e)
    }
  }
}

The method above returns either Successor Failure – for example mail.addFrom might throw an exception if the sender email is invalid. Having said that, is it correct the way I deal with possible exceptions thrown inside the future block?

1
The future method itself does this already.Alexey Romanov

1 Answers

3
votes

You don't need try in future.

val f = future {
  mail.send(body._1.map(_.body).getOrElse(""), body._2.map(_.body).getOrElse(""))
}

f.onFailure{
  case NonFatal(e) => Logger.warn("[%s] error sending email".format(ClassName, subject), e)
}

Future could contain successful result or failure in Try container. You could get Try in onComplete method, or transform Failure to Success using recover method.