Skip to content

Endpoint with NoContent status cannot succeed on client side #3861

@minedeljkovic

Description

@minedeljkovic

Describe the bug
Using endpoint defined with NoContent status fails with Malformed request body failed to decode: Non-empty body cannot be decoded as Unit

To Reproduce

val unitEndpoint = Endpoint((Method.GET / "")).out[Unit](Status.NoContent)
val unitRoute = unitEndpoint.implement(_ => ZIO.unit)
ZIO
  .scoped(
    for {
      _ <- Server.serve(unitRoute).forkScoped
      exec <- ZIO.serviceWith[Client] { client =>
        EndpointExecutor(client, EndpointLocator.fromURL(URL.decode("http://localhost:8080").toOption.get))
      }
      result <- exec(unitEndpoint(()))
    } yield {
      result
    }
  )
  .provide(Server.live, ZLayer.succeed(Server.Config.default), Client.default)

// res0: Exit[Throwable, Unit] = Failure(Die(zio.http.codec.HttpCodecError$MalformedBody: Malformed request body failed to decode: Non-empty body cannot be decoded as Unit,Stack trace for thread "zio-fiber-":
// ))

Expected behaviour
Client request should succeed with unit value.

Desktop (please complete the following information):

  • OS: Linux

Additional context
Using Ok instead of NoContent status succeeds:

val unitEndpoint = Endpoint((Method.GET / "")).out[Unit](Status.Ok)
val unitRoute = unitEndpoint.implement(_ => ZIO.unit)
ZIO
  .scoped(
    for {
      _ <- Server.serve(unitRoute).forkScoped
      exec <- ZIO.serviceWith[Client] { client =>
        EndpointExecutor(client, EndpointLocator.fromURL(URL.decode("http://localhost:8080").toOption.get))
      }
      result <- exec(unitEndpoint(()))
    } yield {
      result
    }
  )
  .provide(Server.live, ZLayer.succeed(Server.Config.default), Client.default)

// res0: Exit[Throwable, Unit] = Success(())

From what I found, the codec on client side depends on the existence of content-length header to exist to be able to decode Unit, while otoh server (rightfully, according to HTTP spec) leaves this header out in the NoContent case.
Relevant code:

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions