reactor / reactor-core

Non-Blocking Reactive Foundation for the JVM
http://projectreactor.io
Apache License 2.0
4.9k stars 1.19k forks source link

Mono.single() fails to detect missing item when combined with Mono.fromSupplier() #2635

Closed j-mok closed 3 years ago

j-mok commented 3 years ago

According to documentation it is perfectly legal to return null from the supplier in a supplier-backed mono. This results in an empty mono. When we chain that with the single() operator the latter doesn't enforce a single value from the upstream mono by emitting an error, but instead simply relays the complete signal downstream.

Expected Behavior

Mono.fromSupplier(() -> null).single() emits NoSuchElementException error.

Actual Behavior

Mono.fromSupplier(() -> null).single() completes.

Steps to Reproduce

@Test
void reproCase() {
StepVerifier.create(
                Mono.fromSupplier(() -> null)
                    //.hide()       // Uncomment to make the test pass
                    .single())
                    .expectErrorMatches(err -> err instanceof NoSuchElementException)
                    .verify();
}

Possible Solution

It seems there's some kind of incorrect internal reaction between the two operators, as sliding hide() between them fixes behavior.

Your Environment

simonbasle commented 3 years ago

This typically looks like a bug with fusion, we'll look into it. Probably affects 3.3.x as well.

OlegDokuka commented 3 years ago

@j-mok this is fixed and will be available with the next release

j-mok commented 3 years ago

Great, thanks!