spring-projects / spring-graphql

Spring Integration for GraphQL
https://spring.io/projects/spring-graphql
Apache License 2.0
1.53k stars 306 forks source link

SSE and WS handlers get into an error handling loop on disconnect #1060

Closed paulbakker closed 1 month ago

paulbakker commented 1 month ago

When an SSE connection disconnects ungracefully, the next call of GraphQLSseHandler.writeResult will fail because of a broken pipe. This is expected. However, the error handling in GraphQLSseHandler now gets into an infinite loop, where the error handling tries to write a message, fails again, and handles that failure the same way. The publisher will never complete and keep emitting values.

I have a possible fix in this PR, which explicitly disposes the subscription on IOException. Feel free to drop this PR for an alternative fix. Note that I have not tested with Webflux, which has its own version of the SSEHandler.

To reproduce:

@Controller
public class SseDatafetcher {
    @SchemaMapping(typeName = "Subscription")
    public Flux<Long> example() {
        return Flux.interval(Duration.ofSeconds(1), Duration.ofSeconds(1))
                .doOnError(e -> System.out.println("Error"))
                .doOnCancel(() -> System.out.println("Cancel"))
                .onErrorComplete();
    }
}

And then curl:

 curl -X POST -N  -H "Content-Type: application/json" -H "Accept: text/event-stream" -d '{"query": "subscription { example }"}' http://localhost:8080/graphql  -i

This will start printing results. The error loop happens when the curl is cmnd-c-ed.

bclozel commented 1 month ago

Thanks for catching this @paulbakker !