[英]how to handle errors in RxJava?
It may sound funny or maybe novice, but I don't understand what it means that something "failed" in Reactive Programming.这听起来可能很有趣,也可能是新手,但我不明白反应式编程中的“失败”是什么意思。 Do you mean a null?
你的意思是null? An empty object?
一个空的 object? someone could please give me examples.
有人可以给我例子。
Some of the scenarios I wish to realize are:我希望实现的一些场景是:
Assuming I send a query parameter and get either a listing with values or an empty listing;假设我发送一个查询参数并获得一个带有值的列表或一个空列表; and lastly, I do not send the query parameter.
最后,我不发送查询参数。
If an empty listing is issued I want to return an exception and a 404 status code.如果发布了一个空列表,我想返回一个异常和一个 404 状态码。
If they do not send the query parameter I want to return an exception and some status code.如果他们不发送查询参数,我想返回一个异常和一些状态码。
And of course, if a list with values is found, return it.当然,如果找到带有值的列表,则返回它。 Will it be possible to make these cases in a single method?
是否有可能用一种方法制作这些案例? how do I do it?
我该怎么做?
First, a reactor operator can ends in different ways:首先,reactor 操作符可以以不同的方式结束:
Secondly, reactive-stream, whatever the implementation (RxJava or Reactor) does not accept null values.其次,反应流,无论实现(RxJava 或 Reactor)不接受 null 值。 It means that trying to produce a null value in/from a reactive stream will either cause an error or an undefined behavior.
这意味着尝试在/从反应式 stream 中生成 null 值将导致错误或未定义的行为。 This is stated in reactive-stream specification, rule 2.13 :
这在反应流规范规则 2.13 中有说明:
Calling [...] onNext [...] MUST return normally except when any provided parameter is null in which case it MUST throw a java.lang.NullPointerException to the caller
调用 [...] onNext [...] 必须正常返回,除非任何提供的参数是null在这种情况下,它必须向调用者抛出 java.lang.NullPointerException
Let's try to produce some simple examples first.让我们首先尝试制作一些简单的示例。
This program shows the possible ways a pipeline can complete:该程序显示了管道可以完成的可能方式:
// Reactive streams does not accept null values:
try {
Mono.just(null);
} catch (NullPointerException e) {
System.out.println("NULL VALUE NOT ACCEPTED !");
}
// Mono/Flux operations stop if an error occurs internally, and send it downstream
try {
Mono.just("Something")
.map(it -> { throw new IllegalStateException("Bouh !"); })
.block();
} catch (IllegalStateException e) {
System.out.println("Error propagated: "+e.getMessage());
}
// A mono or a flux can end "empty". It means that no value or error happened.
// The operation just finished without any result
var result = Mono.just("Hello !")
.filter(it -> !it.endsWith("!"))
// Materialize allow to receive the type of signal produced by the pipeline (next value, error, completion, etc.)
.materialize()
.block();
System.out.println("Input value has been filtered out. No 'next' value " +
"received, just 'completion' signal:" + result.getType());
Its output:其 output:
NULL VALUE NOT ACCEPTED !
Error propagated: Bouh !
Input value has been filtered out. No 'next' value received, just 'completion' signal:onNext
Then, let's look at a program that intercept empty pipelines and errors, and handle them gracefully:那么,我们来看一个拦截空流水线和错误,并优雅处理的程序:
// Errors can be intercepted and replaced by a value:
var result = Mono.error(new IllegalStateException("No !"))
.onErrorResume(err -> Mono.just("Override error: Hello again !"))
.block();
System.out.println(result);
// Empty pipelines can also be replaced by another one that produce a value:
result = Mono.just("Hello !")
.filter(it -> !it.endsWith("!"))
.switchIfEmpty(Mono.just("Override empty: Hello again !"))
.block();
System.out.println(result);
It produces:它产生:
Override error: Hello again !
Override empty: Hello again !
With all this tools, we can solve the problem you describe with your query.使用所有这些工具,我们可以解决您在查询中描述的问题。
Let's mimic it:让我们模仿它:
public static Flux<String> processRequest(String queryParam) {
if (queryParam == null || queryParam.isEmpty()) return Flux.error(new IllegalArgumentException("Bad request"));
return Mono.just(queryParam)
.flatMapMany(param -> Flux.fromArray(param.split("_")))
.switchIfEmpty(Mono.error(new IllegalStateException("No data")));
}
public static void main(String[] args) {
String[] inputs = { null, "hello_world", "___" };
for (var input : inputs) {
try {
String result = processRequest(input)
.collect(Collectors.joining(", ", "[", "]"))
.block();
System.out.println("COMPLETED: " + result);
} catch (Exception e) {
System.out.println("ERROR: " + e.getMessage());
}
}
}
It prints:它打印:
ERROR: Bad request
COMPLETED: [hello, world]
ERROR: No data
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.