传递 Webflux Http 错误
Pass-Through Webflux Http Error
努力弄清楚如何接受从反应性请求收到的异常并将其冒泡(正文和 Http 状态代码将是最少的信息)。
我本来希望使用提到的 ExchangeFilterFunction ,但似乎无法捕捉到错误。我知道它已注册并且 运行 通过
方法
public class MyExchangeFilterFunction implements ExchangeFilterFunction {
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
return next.exchange(request).onErrorMap(MyError.class, c -> new RuntimeException("Ow"));
}
}
注册过滤函数:
WebClient.builder().filter(new MyExchangeFilterFunction())...
转换成错误(因为我不知道如何冒泡):
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class MyError extends RuntimeException{
private Long timestamp;
private String path;
private Integer status;
private String error;
private String message;
}
--------更新------
现在正在使用最新代码抛出错误,但无法弄清楚如何将响应主体塞入 Flux/Mono 错误。
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
return next.exchange(request).map(cr -> {
if(cr.statusCode().isError()) {
return ClientResponse.from(cr).body(
Flux.error(new RuntimeException("OW"))
).build();
} else {
return cr;
}
});
}
更进一步。
return ClientResponse.from(cr)
.body(cr.body(BodyExtractors.toFlux(AnError.class))
.flatMap(err -> Flux.error(new PassThroughException(err))))
.build();
然后在 WebExceptionHandler 中:
AnError error;
if(ex instanceof PassThroughException) {
error = ((PassThroughException) ex).getAnError();
} else {
...
}
exchange.getResponse().setStatusCode(HttpStatus.resolve(error.getStatus()));
exchange.getResponse().getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
byte[] bite = null;
try {
bite = objectMapper.writeValueAsBytes(error);
} catch (JsonProcessingException jpe) {
log.error("Unable to write error to client: {}", ex, jpe);
}
return exchange.getResponse().writeWith(Flux.just(exchange.getResponse().bufferFactory().wrap(bite)));
努力弄清楚如何接受从反应性请求收到的异常并将其冒泡(正文和 Http 状态代码将是最少的信息)。
我本来希望使用提到的 ExchangeFilterFunction
public class MyExchangeFilterFunction implements ExchangeFilterFunction {
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
return next.exchange(request).onErrorMap(MyError.class, c -> new RuntimeException("Ow"));
}
}
注册过滤函数:
WebClient.builder().filter(new MyExchangeFilterFunction())...
转换成错误(因为我不知道如何冒泡):
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class MyError extends RuntimeException{
private Long timestamp;
private String path;
private Integer status;
private String error;
private String message;
}
--------更新------
现在正在使用最新代码抛出错误,但无法弄清楚如何将响应主体塞入 Flux/Mono 错误。
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
return next.exchange(request).map(cr -> {
if(cr.statusCode().isError()) {
return ClientResponse.from(cr).body(
Flux.error(new RuntimeException("OW"))
).build();
} else {
return cr;
}
});
}
return ClientResponse.from(cr)
.body(cr.body(BodyExtractors.toFlux(AnError.class))
.flatMap(err -> Flux.error(new PassThroughException(err))))
.build();
然后在 WebExceptionHandler 中:
AnError error;
if(ex instanceof PassThroughException) {
error = ((PassThroughException) ex).getAnError();
} else {
...
}
exchange.getResponse().setStatusCode(HttpStatus.resolve(error.getStatus()));
exchange.getResponse().getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
byte[] bite = null;
try {
bite = objectMapper.writeValueAsBytes(error);
} catch (JsonProcessingException jpe) {
log.error("Unable to write error to client: {}", ex, jpe);
}
return exchange.getResponse().writeWith(Flux.just(exchange.getResponse().bufferFactory().wrap(bite)));