当前位置: 首页 > 知识库问答 >
问题:

Spring 5反应性异常处理

江永安
2023-03-14

我正在编写一个复杂的应用程序,作为Spring5 Web流的一个实验。我计划在这个应用程序中使用很多技术。我熟悉“旧风格”的@RestController,但现在,我正在编写功能终结点。例如,公司注册服务的后端。我在“旧世界”中寻找类似于“控制建议”的东西。但我真的找不到任何类似于反应性等价物的东西。(或者任何对我有用的东西。)

我有一个非常基本的设置。一个路由函数、一个反应式Cassandra存储库、一个处理程序和一个测试类。存储库操作可能会抛出IllegalArgumentException,我希望通过向客户端返回HTTP状态BadRequest来处理它。作为一个例子,我有能力做到这一点。:-)异常由处理程序类处理。这是我的密码。

路由配置

@Slf4j
@Configuration
@EnableWebFlux
public class RouterConfig {

@Bean
public RouterFunction<ServerResponse> route(@Autowired CompanyHandler handler) {
    return RouterFunctions.route()
            .nest(path("/company"), bc -> bc
                    .GET("/{id}", handler::handleGetCompanyDataRequest)                     
                    .before(request -> {
                        log.info("Request={} has been received.", request.toString());
                        return request;
                    })
            .after((request, response) -> {
                log.info("Response={} has been sent.", response.toString());
                return response;
            }))
            .build();       
    }
}

公司处理程序

@Slf4j
@Component
public class CompanyHandler {

    @Autowired
    private ReactiveCompanyRepository repository;

    // Handle get single company data request
    public Mono<ServerResponse> handleGetCompanyDataRequest(ServerRequest request) {
        //Some validation ges here

        return repository.findById(Mono.just(uuid))
            .flatMap(this::ok)
            .onErrorResume(IllegalArgumentException.class, e -> ServerResponse.badRequest().build())
            .switchIfEmpty(ServerResponse.notFound().build());
    }

    private Mono<ServerResponse> ok (Company c) {
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
            .body(BodyInserters.fromPublisher(Mono.just(c), Company.class));
    }
}

反应性公司报告

@Component
public interface ReactiveCompanyRepository extends ReactiveCassandraRepository<Company, UUID>{

    Mono<Company> findByName(String name);

    Mono<Company> findByEmail(String email);
}

我的问题是. onErrorResume(IllegalArgumentException.class, e-

@SuppressWarnings("unchecked")
@Test
public void testGetCompanyExceptionDuringFind() {

    Mockito.when(repository.findById(Mockito.any(Mono.class))).thenThrow(new IllegalArgumentException("Hahaha"));       

    WebTestClient.bindToRouterFunction(routerConfig.route(companyHandler))
        .build()
        .get().uri("/company/2b851f10-356e-11e9-a847-0f89e1aa5554")
        .accept(MediaType.APPLICATION_JSON_UTF8)
        .exchange()
        .expectStatus().isBadRequest()
        .returnResult(Company.class)
        .getResponseBody();
}

我总是得到HttpStatus 500而不是400。所以它失败了。任何帮助都将不胜感激!

共有1个答案

欧阳勇军
2023-03-14

您的测试并不代表响应式应用编程接口应该如何行为。如果这样的存储库直接抛出异常,我会认为这是一个报告给维护者的错误。

当一个反应式API返回一个反应式类型,比如MonoFlux,所有的错误都不会直接抛出,而是在反应式管道中作为消息发送。

在这种情况下,您的测试用例应该更像:

Mockito.when(repository.findById(Mockito.any(Mono.class)))
   .thenReturn(Mono.error(new IllegalArgumentException("Hahaha")));

有了它,Retor中的onError...操作符将处理这些错误消息。

 类似资料:
  • 我看到了以下关于如何定制spring security webflux的帖子:spring webflux自定义API身份验证 如果我们在ServerSecurityContextRepository.Load中抛出异常,那么Spring会将http头更新为500,而我无法操作此异常。 但是,在controller中抛出的任何错误都可以使用常规的@ControllerAdvision来处理,这只是

  • 问题很简单:我正在寻找一种优雅的方式,将<code>CompletableFuture#与<code>CompletableFuture#supplySync</code>一起使用。这是不起作用的: 我认为背后的想法正是为了处理抛出的情况。然而,如果我这样做,它会起作用: 我可以这样做,但是这看起来很可怕,而且让事情更难维护。有没有一种不需要将所有< code>Exception转换为< code

  • 集成百度移动统计后报错 Q:集成百度移动统计后,开始没什么问题,但最近一段时间每次运行都会先打印出一堆错误信息,并且会重复好多遍 A:造成这种情况是由于sdk捕获异常。可能是网络环境不稳定引起的日志发送失败,网络环境正常的话会自行恢复。可以再继续观察一下,如果仍有问题,可以将问题发送至apptongji@baidu.com 会有专人为您解答。 为什么自定义事件被归入[未知]? Q:为什么自定义事件

  • 我不知道该怎么办。 当我试图从解析器获取语法错误的数量时,它显示0。 编辑: 它返回null。

  • Blade 内置了 异常处理器,在开发者模式下它会将异常输出在前端页面,并在控制台打印堆栈信息,生产环境只打印在控制台。 有些时候不满足我们的需求,这时候就需要自定义异常处理了,比如针对某个自定义的异常进行特殊处理。 我们用一个例子来解释如何操作。 定义了一个名为 TipException 的运行时异常类,用于输出错误消息到前台。 按照上面对异常的处理情况这个异常的堆栈信息会被输出在控制台,生产环

  • 任何方法都可以抛出不同类型的异常。这些异常可能是需要应用程序重新部署来解决的编程错误,或者是不需要重新部署但可以解决的暂时性错误。 Hangfire可以处理所有内部的(属于Hangfire本身)和相关的外部方法(任务,过滤器等)的异常,因此不会导致整个应用程序被关闭。所有内部异常都被记录(所以不要忘记 启用日志),最糟糕的情况是导致后台任务被暂停并延时重试 10 次。 当Hangfire遇到在执行