Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSocketGraphQlTransport does not emit error signal if connection closed before GraphQL session is initialized #1098

Closed
AliakseiKakora opened this issue Dec 9, 2024 · 1 comment
Assignees
Labels
type: bug A general bug
Milestone

Comments

@AliakseiKakora
Copy link

I use spring-graphql 1.3.1 as part of spring-boot-starter-graphql. I want to create a GraphQL subscription to the server which does not belong to me (means I can not do anything on server side to solve my issue). This is how I create subscription and handle events

    WebSocketClient client = new ReactorNettyWebSocketClient(HttpClient.create(),
            () -> WebsocketClientSpec.builder().maxFramePayloadLength(256 * 1024));

    String url = configs.getWsUrl();
    WebSocketGraphQlClient graphQlClient = WebSocketGraphQlClient
            .builder(url, client)
            .keepAlive(Duration.ofSeconds(10))
            .interceptor(new GraphQlClientInterceptor(configs))
            .build();

    Flux<ClientGraphQlResponse> clientGraphQlResponseFlux = graphQlClient
            .document(getQuery(configs))
            .executeSubscription();

    AtomicReference<String> offset = new AtomicReference<>(configs.getOffset());
    Disposable disposable = clientGraphQlResponseFlux
            .map(data -> data.toEntity(BusinessEvent.class))
            .doOnError(error -> {
                log.error("Error in subscription");
            })
            .subscribe(message -> {
                //business logic
            });

And this is how I send Auth token - as part of connection_init payload in the GraphQlClientInterceptor

public class GraphQlClientInterceptor implements WebSocketGraphQlClientInterceptor {

private final SubscriptionManagement configs;

/**
 * Create payload property data. Connection Init is in following format
 * <pre>
 * {
 *   "id": "{GUID}"
 *   "type": "connection_init",
 *   "payload": {
 *     "Authorization": "Bearer {OAUTH TOKEN}
 *     "x-app-key": "{APPLICATION KEY}"
 *   }
 * }<pre/>
 */
@Override
public Mono<Object> connectionInitPayload() {
    Map<String, String> payload = Map.of(
            "x-app-key", configs.getAppKey(),
            "Authorization", configs.getAuthorization()
    );
    return Mono.just(payload);
}

}

In general it works fine - I'm able to connect to the server and process messages. Once some errors occurs I'm able to handle them as well.

But when I started testing flow with invalid auth credentials - the error was not throw to my handler (means doOnError()). I see just log message like this -

"GraphQlSession over ReactorNettyWebSocketSession[id=2127633d, uri=wss://my-url] disconnected with CloseStatus[code=4401, reason=Unauthorised - Invalid credentials]".

Based on my investigation - WebSocketGraphQlTransport tries to terminate request. But at the time when connection_init payload send (and was rejected because of invalid auth token) there no connection yet. Similar issue happens when connection timeout error occurs. In my understanding the issue is - when error occurs on the connection_init phase I do not receive any Errors in the Flux. I'm looking a way to be able to handle any issues that occurs during subscription lifecycle. I would appreciate any help here.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 9, 2024
@rstoyanchev
Copy link
Contributor

In this case the server closes the connection before the GraphQL session is initialized, so at the point where you've been debugging, the transport should be emitting an error on the session sink, but it isn't. I will schedule this for a fix.

@rstoyanchev rstoyanchev self-assigned this Jan 29, 2025
@rstoyanchev rstoyanchev added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Jan 29, 2025
@rstoyanchev rstoyanchev added this to the 1.3.4 milestone Jan 29, 2025
@rstoyanchev rstoyanchev changed the title Handling the WebSocketSession close event if initialization was not successful WebSocketGraphQlTransport does not emit error signal if connection closed before GraphQL session is initialized Jan 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants