Контекст подписчика не найден в doOnError - PullRequest
1 голос
/ 22 сентября 2019

Мне было интересно, может ли кто-нибудь взглянуть на следующий фрагмент кода и сказать мне, почему SubscriberContext внутри doOnError не запускается

public Mono<ServerResponse> handlePlatformAuthenticationResponse(final ServerRequest serverRequest) {
    Mono<MultiValueMap<String, String>> formData = serverRequest.body(BodyExtractors.toFormData());
        return formData
            .flatMap(this::provisionUserAndClass)
            .flatMap(tuple -> Mono.subscriberContext()
                .map(context -> {
                    // this is invoked if provisionUserAndClass completes successfully
                    TelemetryData telemetryData = context.get(TELEMETRY_DATA);
                    LTILaunchRequest<LTILaunchRequestSettings> launchRequest = tuple.getT2();
                    this.addLaunchDetailsToTelemetryContext(launchRequest, telemetryData);
                    return tuple;
                }))
             .doOnError(error -> Mono.subscriberContext()
                    .map(context -> {
                    // this is never invoked if provisionUserAndClass returns a Mono.error
                     TelemetryData telemetryData = context.get(TELEMETRY_DATA);
                     // log telemetryData + error message
                    }))
             .subscriberContext(context -> context.put(TELEMETRY_DATA, new TelemetryData()));
    }

    private Mono<Tuple2<ClassAndUserProvisioningResponse, LTILaunchRequest<LTILaunchRequestSettings>>> provisionUserAndClass(
            LTILaunchRequest<LTILaunchRequestSettings> ltiLaunchRequest) {
        // returning a Mono.error just to see behavior of Mono.subscriberContext() when error occurs. Actual code will call a service method
        return Mono.error(new ProvisioningException("fake")); 
    }

1 Ответ

0 голосов
/ 22 сентября 2019

Для доступа к контексту в случае ошибки вы можете использовать оператор doOnEach:

 .doOnEach(signal -> {
     if (signal.isOnError())
     {
         TelemetryData telemetryData = signal.getContext().get(TELEMETRY_DATA);
         Throwable error = signal.getThrowable();
         // ...
     }
 })

Mono.subscriberContext() может использоваться только в тех операторах, где вы должны вернуть Monoкак flatMap, concatMap и т. д., но не в операторах побочных эффектов, где нет ничего, что могло бы подписаться на Mono<Context>.

...