Skip to content

Commit

Permalink
Add error handler to return appropriate response status code
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed May 8, 2017
1 parent cf7d733 commit 0b85658
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 133 deletions.
7 changes: 4 additions & 3 deletions app/controllers/MispCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controllers

import javax.inject.Inject

import models.InvalidRequestError
import play.api.Logger
import play.api.libs.json.{ JsObject, JsValue }
import play.api.mvc.{ Action, AnyContent, Controller }
Expand All @@ -17,13 +18,13 @@ class MispCtrl @Inject() (mispSrv: MispSrv, implicit val ec: ExecutionContext) e
}

def query: Action[JsValue] = Action.async(parse.json) { request
val module = (request.body \ "module").asOpt[String].getOrElse(sys.error("module not present in request"))
val module = (request.body \ "module").asOpt[String].getOrElse(throw InvalidRequestError("Module parameter is not present in request"))
val (mispType, dataJson) = request.body.as[JsObject].fields
.collectFirst {
case kv @ (k, _) if k != "module" kv
}
.getOrElse(sys.error("invalid request"))
val data = dataJson.asOpt[String].getOrElse(sys.error("data has invalid type (expected string)"))
.getOrElse(throw InvalidRequestError("Request doesn't contain data to analyze"))
val data = dataJson.asOpt[String].getOrElse(throw InvalidRequestError("Data has invalid type (expected string)"))
mispSrv.query(module, mispType, data)
.map(Ok(_))
}
Expand Down
16 changes: 0 additions & 16 deletions app/models/Analyzer.scala.orig

This file was deleted.

9 changes: 0 additions & 9 deletions app/models/Analyzer.scala.rej

This file was deleted.

8 changes: 8 additions & 0 deletions app/models/Errors.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package models

abstract class CortexError(message: String) extends Exception(message)

case class JobNotFoundError(jobId: String) extends CortexError(s"Job $jobId not found")
case class UnexpectedError(message: String) extends CortexError(message)
case class AnalyzerNotFoundError(analyzerId: String) extends CortexError(s"Analyzer $analyzerId not found")
case class InvalidRequestError(message: String) extends CortexError(message)
46 changes: 0 additions & 46 deletions app/models/JsonFormat.scala.orig

This file was deleted.

51 changes: 0 additions & 51 deletions app/models/JsonFormat.scala.rej

This file was deleted.

2 changes: 1 addition & 1 deletion app/services/AnalyzerSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AnalyzerSrv @Inject() (
def analyze(analyzerId: String, artifact: Artifact): Future[Job] = {
get(analyzerId)
.map { analyzer analyze(analyzer, artifact) }
.getOrElse(sys.error("analyzer not found"))
.getOrElse(throw AnalyzerNotFoundError(analyzerId))
}

def analyze(analyzer: Analyzer, artifact: Artifact): Future[Job] = {
Expand Down
27 changes: 27 additions & 0 deletions app/services/ErrorHandler.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package services

import models.{ AnalyzerNotFoundError, InvalidRequestError, JobNotFoundError, UnexpectedError }
import play.api.Logger
import play.api.http.HttpErrorHandler
import play.api.mvc.{ RequestHeader, Result, Results }

import scala.concurrent.Future

class ErrorHandler extends HttpErrorHandler {
private[ErrorHandler] lazy val logger = Logger(getClass)
def onClientError(request: RequestHeader, statusCode: Int, message: String): Future[Result] = Future.successful {
Results.Status(statusCode)(s"A client error occurred on ${request.method} ${request.uri} : $message")
}

def onServerError(request: RequestHeader, exception: Throwable): Future[Result] = {
val result = exception match {
case JobNotFoundError(jobId) Results.NotFound(s"Job $jobId not found")
case UnexpectedError(message) Results.InternalServerError(message)
case AnalyzerNotFoundError(analyzerId) Results.NotFound(s"analyzer $analyzerId not found")
case InvalidRequestError(message) Results.BadRequest(message)
case error Results.InternalServerError(s"Unexpected error: $error")
}
Logger.info(s"${request.method} ${request.uri} returned ${result.header.status}", exception)
Future.successful(result)
}
}
13 changes: 6 additions & 7 deletions app/services/JobSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import scala.concurrent.{ ExecutionContext, Future, Promise }
import scala.util.Random

class JobSrv @Inject() (
//analyzerSrv: AnalyzerSrv,
@Named("JobActor") jobActor: ActorRef,
implicit val ec: ExecutionContext,
implicit val system: ActorSystem) {
Expand All @@ -27,20 +26,20 @@ class JobSrv @Inject() (
def list(dataTypeFilter: Option[String], dataFilter: Option[String], analyzerFilter: Option[String], start: Int, limit: Int): Future[(Int, Seq[Job])] = {
(jobActor ? ListJobs(dataTypeFilter, dataFilter, analyzerFilter, start, limit)).map {
case JobList(total, jobs) total jobs
case _ sys.error("TODO")
case m throw UnexpectedError(s"JobActor.list replies with unexpected message: $m (${m.getClass})")
}
}

def get(jobId: String): Future[Job] = (jobActor ? GetJob(jobId)).map {
case j: Job j
case JobNotFound sys.error("job not found")
case _ sys.error("TODO")
case JobNotFound throw JobNotFoundError(jobId)
case m throw UnexpectedError(s"JobActor.GetJob replies with unexpected message: $m (${m.getClass})")
}

def create(analyzer: Analyzer, artifact: Artifact, report: Future[Report]): Future[Job] = {
(jobActor ? CreateJob(artifact, analyzer, report)) map {
case job: Job job
case _ sys.error("TODO")
case m throw UnexpectedError(s"JobActor.CreateJob replies with unexpected message: $m (${m.getClass})")
}
}

Expand All @@ -61,8 +60,8 @@ class JobSrv @Inject() (
def remove(jobId: String): Future[Unit] = {
(jobActor ? RemoveJob(jobId)).map {
case JobRemoved ()
case JobNotFound sys.error("job not found")
case _ sys.error("TODO")
case JobNotFound throw JobNotFoundError(jobId)
case m throw UnexpectedError(s"JobActor.RemoveJob replies with unexpected message: $m (${m.getClass})")
}
}

Expand Down
3 changes: 3 additions & 0 deletions conf/reference.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# handler for errors (transform exception to related http status code
play.http.errorHandler = services.ErrorHandler

analyzer {
# Directory that holds analyzers
path = analyzers
Expand Down

0 comments on commit 0b85658

Please sign in to comment.