2017-05-30 158 views
4

我試圖使用WebFlux,我看到的行爲我不太明白,我懷疑這是WebFlux或可能反應堆中的錯誤,但我需要確認。onErrorResume不按預期工作

我試圖創建一個由非常簡單 HandlerFunction試圖返回200響應的最小可重複的情況,但會引發身體創建過程中的異常,然後嘗試使用onErrorResume,而不是返回404響應。

處理程序看起來像這樣:

public Mono<ServerResponse> reproduce(ServerRequest request){ 
     return ServerResponse.ok() 
     .contentType(APPLICATION_JSON) 
     .body(Mono.fromCallable(this::trigger),String.class) 
     .onErrorResume(MinimalExampleException.class,e->ServerResponse.notFound().build()); 
} 

調用相關的終點,我會得到一個404迴應時,我所期望的。相反,我看到的是一個500響應日誌消息,指示Spring認爲請求處理期間存在未處理的異常。

當我斷點onErrorResume的內部予見正在註冊兩個處理機,一個我的方法中登記上述以及做爲所正在註冊由彈簧(內側的RouterFunctions.toHttpHandler),用於ResponseStatusException實例之一。然後,在處理請求期間,我只看到第二個處理程序(由Spring註冊的處理程序)被調用,而不是匹配所拋出的異常,然後落入根級處理程序。

附近,我可以告訴,春季覆蓋onErrorResume在路由器級防止我在Handler中註冊的人被調用。這是預期的行爲?有沒有更好的方法來完成我所嘗試的?

回答

4

該框架確實有一個「全面通用」,在以下任何一個調用之前調用.body(...)。這是設計,我認爲這是很難避免的。

我看到3種溶液:

  1. 轉動運營鏈圍繞

像這樣:

return Mono.fromCallable(this::trigger) 
      .flatMap(s -> ServerResponse.ok() 
         .contentType(MediaType.TEXT_PLAIN) 
         .syncBody(s)) 
      .onErrorResume(MinimalExampleException.class, 
         e -> ServerResponse.notFound().build()); 
  • 使用ResponseStatusException
  • 你可以把onErrorResume在相同的水平fromCallable()(身體呼叫內)經由一個錯誤單聲道到特定錯誤轉換成ResponseStatusException

    Mono.fromCallable(this::trigger) 
        .onErrorResume(MinimalExampleException.class, 
         e->Mono.error(new ResponseStatusException(404, "reason message", e))) 
    
  • 使用一個異常處理程序
  • 您應該能夠使用@ExceptionHandler註解方法來處理您的特定異常。

    +0

    @orclev編輯使用正確的彈簧5異常 –

    +0

    第三個選項似乎沒有工作出於某種原因。 第二個選項可以進行小修改(ResponseStatusException將HttpStatus作爲其第一個參數,而不是int文本)。 我想我最喜歡第一個選項。 – Orclev

    +0

    我懷疑@ExceptionHandler只能使用帶註釋的控制器:https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-ann-initbinder –