Skip to content

Commit

Permalink
Merge pull request #81 from innFactory/feature/custom-error-response
Browse files Browse the repository at this point in the history
feat: add ability to add custom error responses
  • Loading branch information
patsta32 authored Dec 2, 2022
2 parents 56075c4 + 030a67b commit b7b4a31
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 36 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,7 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
)

def handleFailure(error: ContextRouteError): Result =
Results.Status(error.statusCode)(
Json.toJson(
RoutingErrorResponse(error.message, error.additionalInfoErrorCode, error.additionalInformation)
)
)
Results.Status(error.statusCode)(error.toJson)

private def handleSuccess(output: O, code: Int): Result = {
val outputMetadata = outputMetadataEncoder.encode(output)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.innfactory.smithy4play.client

import de.innfactory.smithy4play.{ logger, ClientResponse, RoutingErrorResponse }
import play.api.libs.json.Json
import de.innfactory.smithy4play.{ logger, ClientResponse }
import play.api.libs.json.{ Json, Reads }

import scala.concurrent.duration.{ Duration, DurationInt }
import scala.concurrent.{ Await, ExecutionContext }
Expand Down Expand Up @@ -36,12 +36,12 @@ object SmithyPlayTestUtils {
}

implicit class EnhancedSmithyPlayClientEndpointErrorResponse(errorResponse: SmithyPlayClientEndpointErrorResponse) {
def toErrorResponse: RoutingErrorResponse = errorResponse.error.toErrorResponse
def toErrorResponse[T](implicit reads: Reads[T]): T = errorResponse.error.toErrorResponse
}

implicit class EnhancedByteArray(error: Array[Byte]) {
def toErrorString: String = new String(error)
def toErrorResponse: RoutingErrorResponse = Json.parse(error).as[RoutingErrorResponse]
def toErrorString: String = new String(error)
def toErrorResponse[T](implicit reads: Reads[T]): T = Json.parse(error).as[T]
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import cats.data.{ EitherT, Kleisli }
import de.innfactory.smithy4play.client.{ SmithyPlayClientEndpointErrorResponse, SmithyPlayClientEndpointResponse }
import org.slf4j
import play.api.Logger
import play.api.libs.json.{ JsValue, Json }
import play.api.mvc.{ Headers, RequestHeader }
import smithy4s.http.{ CaseInsensitive, HttpEndpoint, PayloadError }

Expand All @@ -15,10 +16,8 @@ package object smithy4play {

trait ContextRouteError {
def message: String
def additionalInfoToLog: Option[String]
def additionalInformation: Option[String]
def additionalInfoErrorCode: Option[String]
def statusCode: Int
def toJson: JsValue
}

type ClientResponse[O] = Future[Either[SmithyPlayClientEndpointErrorResponse, SmithyPlayClientEndpointResponse[O]]]
Expand All @@ -32,9 +31,11 @@ package object smithy4play {
statusCode: Int,
additionalInformation: Option[String] = None
) extends ContextRouteError {
override def additionalInfoToLog: Option[String] = None
override def toJson: JsValue = Json.toJson(this)(Smithy4PlayError.format)
}

override def additionalInfoErrorCode: Option[String] = None
object Smithy4PlayError {
implicit val format = Json.format[Smithy4PlayError]
}

private[smithy4play] val logger: slf4j.Logger = Logger("smithy4play").logger
Expand Down
13 changes: 2 additions & 11 deletions smithy4playTest/app/controller/TestController.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controller

import cats.data.{ EitherT, Kleisli }
import controller.models.TestError
import de.innfactory.smithy4play.{ AutoRouting, ContextRoute, ContextRouteError }
import play.api.mvc.ControllerComponents
import smithy4s.ByteArray
Expand Down Expand Up @@ -45,17 +46,7 @@ class TestController @Inject() (implicit
}

override def testThatReturnsError(): ContextRoute[Unit] = Kleisli { rc =>
EitherT.leftT[Future, Unit](new ContextRouteError {
override def message: String = "this is supposed to fail"

override def additionalInfoToLog: Option[String] = None

override def additionalInfoErrorCode: Option[String] = None

override def additionalInformation: Option[String] = None

override def statusCode: Int = 500
})
EitherT.leftT[Future, Unit](TestError("this is supposed to fail"))
}

override def testAuth(): ContextRoute[Unit] = Kleisli { rc =>
Expand Down
15 changes: 15 additions & 0 deletions smithy4playTest/app/controller/models/TestError.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package controller.models

import de.innfactory.smithy4play.ContextRouteError
import play.api.libs.json.{ JsValue, Json }

case class TestError(
message: String
) extends ContextRouteError {
override def statusCode: Int = 500
override def toJson: JsValue = Json.toJson(this)(TestError.format)
}

object TestError {
implicit val format = Json.format[TestError]
}
3 changes: 2 additions & 1 deletion smithy4playTest/test/TestControllerTest.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import controller.models.TestError
import de.innfactory.smithy4play.client.GenericAPIClient.EnhancedGenericAPIClient
import de.innfactory.smithy4play.client.{ RequestClient, SmithyClientResponse }
import de.innfactory.smithy4play.client.SmithyPlayTestUtils._
Expand Down Expand Up @@ -129,7 +130,7 @@ class TestControllerTest extends PlaySpec with BaseOneAppPerSuite with FakeAppli
"route to error Endpoint" in {
val result = genericClient.testThatReturnsError().awaitLeft

result.toErrorResponse.message must include("fail")
result.toErrorResponse[TestError].message must include("fail")
result.statusCode mustBe 500
}

Expand Down

0 comments on commit b7b4a31

Please sign in to comment.