Reputation: 277
Multiple times throughout my code I use the following pattern to recover a failing future:
myFuture.recover {
case t =>
Logger.error(s"foo bar foo, exception: ${t.getMessage}.")
InternalServerError(views.html.error(request, Messages("error.foo")))
}
I am now looking for a way to encapsulate this behavior in order to remove code duplication. I tried to wrap it in a class but strangely, I cannot resolve InternalServerError
inside the apply
method.
class MyError(t: Throwable, logMsg: String, message: String) {
def apply(t: Throwable, logMsg: String, message: String) = {
Logger.error(logMsg)
InternalServerError(views.html.error(request, message))
}
}
Any idea how I can solve this? Also how do I go about the request
parameter?
Upvotes: 0
Views: 58
Reputation: 14825
Code Reuse
Use implicit class
to extend the functionality of the Future
and put the implicit class
inside the package object
or object. Import the package object/object and use the code whenever you need it.
object common {
implicit class FutureUtils(future: Future[Result]) {
def graceful(implicit req: Request, msg: String): Future[Result] = {
future.recover { case th =>
import play.api.mvc.Results._
Logger.error(logMsg)
InternalServerError(views.html.error(request, message))
}
}
}
}
import common._
class Foo extends Controller {
def bar = Action { implicit req =>
myFuture.graceful(Messages("foo.bar"))
}
}
Upvotes: 3
Reputation: 10662
I'm quite sure you meant the apply
method to be part of the companion object, not the class itself.
As for the resolution problem, you'll have to import it like this:
object MyError {
def apply(t: Throwable, logMsg: String, message: String, request: Request): Result = {
import play.api.mvc.Results._
Logger.error(logMsg)
InternalServerError(views.html.error(request, message))
}
}
Then you can do
MyError(t, "log something", "message", request)
as the last line inside a controller Action
Upvotes: 1