-
Notifications
You must be signed in to change notification settings - Fork 456
Open
Description
Tapir version: 1.11.49
Scala version: 2.13.1
Describe the bug
tapir reject handler doesn't works for Vertx web server
How to reproduce?
//> using scala 2.13.16
//> using dep org.typelevel::cats-effect:3.6.3
//> using dep com.softwaremill.sttp.tapir::tapir-vertx-server-cats:1.11.49
//> using dep com.softwaremill.sttp.tapir::tapir-http4s-server:1.11.49
//> using dep org.http4s::http4s-ember-server:0.23.32
import cats.effect._
import cats.effect.std.Dispatcher
import com.comcast.ip4s.Port
import io.vertx.core.Vertx
import io.vertx.ext.web.Router
import org.http4s.ember.server.EmberServerBuilder
import sttp.model.StatusCode
import sttp.tapir._
import sttp.tapir.server.ServerEndpoint
import sttp.tapir.server.http4s.{Http4sServerInterpreter, Http4sServerOptions}
import sttp.tapir.server.interceptor.CustomiseInterceptors
import sttp.tapir.server.interceptor.reject.DefaultRejectHandler
import sttp.tapir.server.model.ValuedEndpointOutput
import sttp.tapir.server.vertx.cats.VertxCatsServerInterpreter._
import sttp.tapir.server.vertx.cats.{VertxCatsServerInterpreter, VertxCatsServerOptions}
object App extends IOApp {
private val responseEndpoint: ServerEndpoint[Any, IO] =
endpoint
.get
.in("response")
.in(query[String]("key"))
.out(plainBody[String])
.serverLogicSuccessPure(req => s"Response: $req")
private val okEndpoint: ServerEndpoint[Any, IO] =
endpoint
.get
.in("ok")
.out(plainBody[String])
.serverLogicSuccessPure(_ => "OK")
private val endpoints: List[ServerEndpoint[Any, IO]] = List(responseEndpoint, okEndpoint)
private def addNotFoundHandler[O]: CustomiseInterceptors[IO, O] => CustomiseInterceptors[IO, O] =
_
.rejectHandler(
DefaultRejectHandler[IO](
(sc: StatusCode, m: String) => ValuedEndpointOutput(statusCode.and(stringBody), (sc, m)),
Some((StatusCode.Ok, "Custom Not Found Response"))
)
)
def runAsVertx: IO[Nothing] =
Dispatcher.parallel[IO].flatMap { dispatcher =>
Resource
.make(
IO.delay {
val vertx = Vertx.vertx()
val server = vertx.createHttpServer()
val router = Router.router(vertx)
val options =
addNotFoundHandler(VertxCatsServerOptions.customiseInterceptors[IO](dispatcher))
.options
endpoints.foreach(VertxCatsServerInterpreter[IO](options).route(_)(router))
server.requestHandler(router).listen(8080)
}.flatMap(_.asF[IO])
) { server =>
IO.delay(server.close).flatMap(_.asF[IO].void)
}
}
.use(_ => IO.println("Server started on port 8080") >> IO.never)
def runAsHttp4s: IO[Nothing] = {
val options =
addNotFoundHandler(Http4sServerOptions.customiseInterceptors[IO])
.options
EmberServerBuilder
.default[IO]
.withHttpApp(Http4sServerInterpreter[IO](options).toRoutes(endpoints).orNotFound)
.withPort(Port.fromInt(8080).get)
.build
.use(_ => IO.println("Server started on port 8080") >> IO.never)
}
override def run(args: List[String]): IO[ExitCode] = runAsVertx // runAsHttp4s
}First run with runAsVertx, second run with runAsHttp4s. Then call:
curl http://localhost:8080/something- With
runAsVertx, I got 404 response (default vertx response, but I expects 200 withCustom Not Found Response):<html><body><h1>Resource not found</h1></body></html> - With
runAsHttp4s, I got 200 response (as expected):Custom Not Found Response
Metadata
Metadata
Assignees
Labels
No labels