I am using play framework
with scala
and here is a scenario on which I would like to have your opinion.
Let's say I have 2 custom exceptions that I can throw, which are EmailTaken
and AuthFail
. What I need to do here is, whenever any of these 2 exceptions happen, I need to return a json
with 3 keys success
, errorCode
and message
, in case of all other exceptions let Play
's default error handling take charge. Now for all custom exceptions success
will always be false
, each exception would have a unique errorCode
integer value and a unique message
string both of which remain fixed for a particular exception.
Now I saw people using case class
(they can be pattern matched) or class
(saw some java examples) for exception but I didn't see the point of creating them because for any particular exception I don't see the point of creating more than 1 object because its attributes don't have to be changed (I could create a case class
with all default parameters but why?). So I created an object
for each exception and then I throw that exception object in the controller and then in the Global
object I rely on the getCause
of the exception.
// custom exceptions code
trait AppException extends Exception {
val success = false
def errorCode: Int
def message: String
override def fillInStackTrace(): Throwable = {
this
}
}
object EmailTaken extends AppException {
val errorCode = 1
val message = "email already used"
}
object AuthFail extends AppException {
val errorCode = 2
val message = "id/password dont match"
}
// in Play's controller
object Application extends Controller {
def test = Action {
throw EmailTaken
Ok("Test Page")
}
}
// in Play's Global object
object Global extends GlobalSettings {
override def onError(request: RequestHeader, ex: Throwable) = {
ex.getCause match {
case c: AppException => // a known custom exception
Future.successful(InternalServerError(
Json.toJson(Json.obj(
"success"-> c.success,
"message"-> c.message,
"errorCode"-> c.errorCode
))
))
case _ =>
super.onError(request, ex)
}
}
}
I understand that if AuthFail
was A case class
I would have returned new AuthFail()
and pattern matched on that exception object. Also, I could have used isInstanceOf[AppException]
to check for custom exceptions. But are there any problems with this approach? Also, what are the other good approaches I can take? I don't have much experience with Scala or Java.