playframework / playframework/playframework

HttpEntity.Streamed swallows stream failure exception

Open
#8,062 8 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

status:needs-verification type:defect
Dominant language
Scala
Stars
12.6k
Forks
4k
Avg merge
2d 3h
Merged PRs (30d)
29

Description

Play 2.6.7, and 2.6.13

When a request throws an exception you normally get a 500 response and an exception is logged. This behavior can be modified in the HttpErrorHandler. Eg sending the exception to a bug tracking system.

But for streamed responses where the stream fails the exception is just swallowed and the connection is closed. (curl: (56) Recv failure: Connection reset by peer)
I guess that for chunked responses there is no way to change the response code after the streaming starts. However this exception should at least be logged as this is similar to the 500 case.

In our case we have a nginx in front of play and it makes this issue worse because nginx translates the connection reset into a normal request ending. So the consumers of our api just got a 200 with an empty response.

We spent quite some time on finding the source of our "empty" chunked response and a logged exception could have made this much easier to find.

as a workaround we currently do this:

        val ndJson = jsonMessages.recoverWithRetries(0, {
          case e =>
            log.error("Stream failed", e)
            Source.single(Json.obj("error" -> "error during streaming")).concat(
              Source.failed(e)
            )
        }) via NDJSON.write
        Result(
          header = ResponseHeader(200, Map.empty),
          body = HttpEntity.Streamed(ndJson, None, Some("application/x-ndjson"))
        )

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the HttpEntity.Streamed response path and compare its stream-failure handling with the HttpErrorHandler behavior described in the issue. Reproduce the failing chunked response using the supplied ndJson workaround, then verify that a stream exception is logged while the existing response handling remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
scala
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.