简体   繁体   中英

Micronaut map empty Flowable to 404

Given: I have a service which produces a Flowable<T> . This Flowable<T> can be empty.

I have a controller, which looks similar to this:

@Controller("/api}")
class ApiController constructor( private val myService: MyService) {
    @Get("/")
    @Produces(MediaType.APPLICATION_JSON)
    fun getSomething(): Flowable<T> {
        return myService.get()
    }
}

What I want to achieve: when the flowable is empty -> throw a HttpStatusException(404) .

Otherwise return the flowable with the data inside.

What I already tried

I tried different combinations of the following RxJava Operators:

  1. doOnError
  2. onErrorResumeNext
  3. onErrorReturn
  4. switchIfEmpty
  5. ...

What I experienced

None of the options produced a 404 in the Browser/Postman.

A couple of options are just doing "nothing". Which means, that the page is not loading in the browser.

Other options are creating "OK" (200) responses with empty bodies.

And some are creating a CompositeException ...

Does someone have a hint for me?

Update : as suggested:

@Controller("/api")
class HelloController {
    @Get("/")
    @Produces(MediaType.APPLICATION_JSON)
    fun get(): Flowable<String> {
        return Flowable.empty<String>()
                .switchIfEmpty {
            it.onError(HttpStatusException(HttpStatus.NOT_FOUND,""))
        }
    }
}

This produces the following, when I call it with firefox:

HttpResponseStatus: 200
HttpContent: [
Yes, the closing bracet is missing!

A possible Solution is, to use Maybe instead of Flowable.

@Controller("/api")
class HelloController {
    @Get("/")
    @Produces(MediaType.APPLICATION_JSON)
    fun get(): Maybe<String> {
        return Flowable.empty<String>()
            .toList()
            .flatMapMaybe { x ->
                if (x.size == 0)
                    Maybe.empty<String>()
                else
                    Maybe.just(x)
            }           
        }
    }
}

It is not the best solution, but a working one.

I don't know Micronaut, but I think this may be what you want:

Flowable.empty<Int>()
    .switchIfEmpty { it.onError(Exception()) } // or HttpStatusException(404) in your case
    .subscribe({
        println(it)
    }, {
        it.printStackTrace()
    })

The Flowable is empty, and what you get downstream is the Exception created inside switchIfEmpty . Note that you have to call it.onError inside switchIfEmpty .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM