aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Smith <zach@driver.xyz>2017-10-19 13:49:22 -0700
committerZach Smith <zach@driver.xyz>2017-10-31 09:19:04 -0700
commite7d849b55f975f1c119cebb22f95d9de903ae3c3 (patch)
treea593bc7ac4722c910efc0f026543ecee8badd14d
parent2e2d4df8749c02df20c29a36090daa1a76344656 (diff)
downloaddriver-core-e7d849b55f975f1c119cebb22f95d9de903ae3c3.tar.gz
driver-core-e7d849b55f975f1c119cebb22f95d9de903ae3c3.tar.bz2
driver-core-e7d849b55f975f1c119cebb22f95d9de903ae3c3.zip
Stop catching throwable, remove PHI filtering, move status code logic to exception handler
-rw-r--r--src/main/scala/xyz/driver/core/rest/DriverRoute.scala54
-rw-r--r--src/main/scala/xyz/driver/core/rest/errors/serviceException.scala40
2 files changed, 46 insertions, 48 deletions
diff --git a/src/main/scala/xyz/driver/core/rest/DriverRoute.scala b/src/main/scala/xyz/driver/core/rest/DriverRoute.scala
index f3260d0..be9c783 100644
--- a/src/main/scala/xyz/driver/core/rest/DriverRoute.scala
+++ b/src/main/scala/xyz/driver/core/rest/DriverRoute.scala
@@ -3,14 +3,14 @@ package xyz.driver.core.rest
import java.sql.SQLException
import akka.http.scaladsl.model._
-import akka.http.scaladsl.model.StatusCodes.{BadRequest, Conflict, InternalServerError}
+import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{ExceptionHandler, RequestContext, Route}
import com.typesafe.scalalogging.Logger
import org.slf4j.MDC
import xyz.driver.core.rest
-import xyz.driver.core.rest.errors.ServiceException
+import xyz.driver.core.rest.errors._
import scala.compat.Platform.ConcurrentModificationException
@@ -29,38 +29,58 @@ trait DriverRoute {
* @return Exception handling route for exception type
*/
protected def exceptionHandler: PartialFunction[Throwable, Route] = {
- case api: ServiceException if api.isPatientSensitive =>
- ctx =>
- log.info("PHI Sensitive error")
- errorResponse(ctx, InternalServerError, "Server error", api)(ctx)
-
- case api: ServiceException =>
- ctx =>
- log.info("API Error")
- errorResponse(ctx, api.statusCode, api.message, api)(ctx)
+ case serviceException: ServiceException =>
+ serviceExceptionHandler(serviceException)
case is: IllegalStateException =>
ctx =>
log.warn(s"Request is not allowed to ${ctx.request.method} ${ctx.request.uri}", is)
- errorResponse(ctx, BadRequest, message = is.getMessage, is)(ctx)
+ errorResponse(ctx, StatusCodes.BadRequest, message = is.getMessage, is)(ctx)
case cm: ConcurrentModificationException =>
ctx =>
log.warn(s"Concurrent modification of the resource ${ctx.request.method} ${ctx.request.uri}", cm)
- errorResponse(ctx, Conflict, "Resource was changed concurrently, try requesting a newer version", cm)(ctx)
+ errorResponse(ctx,
+ StatusCodes.Conflict,
+ "Resource was changed concurrently, try requesting a newer version",
+ cm)(ctx)
case se: SQLException =>
ctx =>
log.warn(s"Database exception for the resource ${ctx.request.method} ${ctx.request.uri}", se)
- errorResponse(ctx, InternalServerError, "Data access error", se)(ctx)
+ errorResponse(ctx, StatusCodes.InternalServerError, "Data access error", se)(ctx)
- case t: Throwable =>
+ case t: Exception =>
ctx =>
log.warn(s"Request to ${ctx.request.method} ${ctx.request.uri} could not be handled normally", t)
- errorResponse(ctx, InternalServerError, t.getMessage, t)(ctx)
+ errorResponse(ctx, StatusCodes.InternalServerError, t.getMessage, t)(ctx)
+ }
+
+ protected def serviceExceptionHandler(serviceException: ServiceException): Route = {
+ val statusCode = serviceException match {
+ case e: InvalidInputException =>
+ log.info("Invalid client input error", e)
+ StatusCodes.BadRequest
+ case e: InvalidActionException =>
+ log.info("Invalid client action error", e)
+ StatusCodes.Forbidden
+ case e: ResourceNotFoundException =>
+ log.info("Resource not found error", e)
+ StatusCodes.NotFound
+ case e: ExternalServiceTimeoutException =>
+ log.error("Service timeout error", e)
+ StatusCodes.GatewayTimeout
+ case e: DatabaseException =>
+ log.error("Database error", e)
+ StatusCodes.InternalServerError
+ }
+
+ { (ctx: RequestContext) =>
+ errorResponse(ctx, statusCode, serviceException.message, serviceException)(ctx)
+ }
}
- protected def errorResponse[T <: Throwable](ctx: RequestContext,
+ protected def errorResponse[T <: Exception](ctx: RequestContext,
statusCode: StatusCode,
message: String,
exception: T): Route = {
diff --git a/src/main/scala/xyz/driver/core/rest/errors/serviceException.scala b/src/main/scala/xyz/driver/core/rest/errors/serviceException.scala
index 94f9734..7aa70bf 100644
--- a/src/main/scala/xyz/driver/core/rest/errors/serviceException.scala
+++ b/src/main/scala/xyz/driver/core/rest/errors/serviceException.scala
@@ -1,41 +1,19 @@
package xyz.driver.core.rest.errors
-import akka.http.scaladsl.model.{StatusCode, StatusCodes}
-
abstract class ServiceException extends Exception {
- def isPatientSensitive: Boolean = false
-
- def statusCode: StatusCode
def message: String
}
-final case class InvalidInputException(override val message: String = "Invalid input",
- override val isPatientSensitive: Boolean = false)
- extends ServiceException {
- override def statusCode: StatusCode = StatusCodes.BadRequest
-}
+final case class InvalidInputException(override val message: String = "Invalid input") extends ServiceException
-final case class InvalidActionException(override val message: String = "This action is not allowed",
- override val isPatientSensitive: Boolean = false)
- extends ServiceException {
- override def statusCode: StatusCode = StatusCodes.Forbidden
-}
+final case class InvalidActionException(override val message: String = "This action is not allowed")
+ extends ServiceException
-final case class ResourceNotFoundException(override val message: String = "Resource not found",
- override val isPatientSensitive: Boolean = false)
- extends ServiceException {
- override def statusCode: StatusCode = StatusCodes.NotFound
-}
+final case class ResourceNotFoundException(override val message: String = "Resource not found")
+ extends ServiceException
-final case class ExternalServiceTimeoutException(override val message: String =
- "Another service took too long to respond",
- override val isPatientSensitive: Boolean = false)
- extends ServiceException {
- override def statusCode: StatusCode = StatusCodes.GatewayTimeout
-}
+final case class ExternalServiceTimeoutException(
+ override val message: String = "Another service took too long to respond")
+ extends ServiceException
-final case class DatabaseException(override val message: String = "Database access error",
- override val isPatientSensitive: Boolean = false)
- extends ServiceException {
- override def statusCode: StatusCode = StatusCodes.InternalServerError
-}
+final case class DatabaseException(override val message: String = "Database access error") extends ServiceException