2017-09-26 3 views
-1

グローバルなエラーハンドラがカスタムコンバータ内でスローされた例外をキャッチしないSpring(およびkotlin?)の問題に直面しています。スプリングフレームワークでカスタムコンバータの例外が発生する

私はspringサポートstring - > UUIDのマッピングをデフォルトで知っていますが、実際に例外がスローされたかどうかを明示的に確認したいと考えました。それは次のコンバーターです。この動作は、自分でコンバータを実装しても実装しなくても同じです。次のように

私WebMvcConfugurationに見えます:

@Configuration 
class WebMvcConfiguration : WebMvcConfigurerAdapter() { 

    override fun addFormatters(registry: FormatterRegistry) { 
     super.addFormatters(registry) 
     registry.addConverter(Converter<String, UUID> { str -> 
      try { 
       UUID.fromString(str) 
      } catch(e: IllegalArgumentException){ 


     throw RuntimeException(e) 
     } 
    }) 
} 

をそして、これは私のGlobalExceptionHandlerです:

@ControllerAdvice 
class GlobalExceptionHandler : ResponseEntityExceptionHandler() { 

    @ExceptionHandler(Exception::class) 
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 
    @ResponseBody 
    fun handleException(ex: Exception): ApiError { 
     logger.info(ex.message, ex) 
     return ApiError(ex.message) 
    } 
} 

そして最後に、コントローラ(それはまた、私は簡潔にするため省略さ他のハンドラを、含まれています):

@Controller 
class MyController : ApiBaseController() { 
    @GetMapping("/something/{id}") 
    fun getSomething(@PathVariable("id") id: UUID) { 
     throw NotImplementedError() 
    } 
} 

制御内の例外ler(例えばNotImplementedError)メソッドはうまく捕まえられます。しかし、無効なUUIDが渡されたときにコンバーター内でIllegalArgumentExceptionがスローされ、springが空の400応答を返します。

私の質問は次のとおりです:どのようにこれらのエラーをキャッチし、カスタムエラーメッセージで応答しますか?

ありがとうございます!他の人が継承BaseControllerを実装し、そこに働く例外ハンドラを追加し、代わりに@ControllerAdviceを使用しての

:いくつかのより多くの試行錯誤の後

+0

downvoteが高く評価されるだろう何のためにあるのかを説明。 –

答えて

0

私は同じ問題を抱えていました。春はいずれもIllegalArgumentException(私の場合はConversionFailedException)を飲み込んだ。

私が探していた動作を取得するには、つまり、リストされた例外のみを処理し、他の例外に対してデフォルトの動作を使用する場合は、ResponseEntityExceptionHandlerを拡張しないでください。

例:

@ControllerAdvice 
public class RestResponseEntityExceptionHandler{ 

    @ExceptionHandler(value = {NotFoundException.class}) 
    public ResponseEntity<Object> handleNotFound(NotFoundException e, WebRequest request){ 
     return new ResponseEntity<>(e.getMessage(), new HttpHeaders(), HttpStatus.NOT_FOUND); 
    } 

} 
+0

ありがとう! ResponseEntityExceptionHandlerを拡張することも私の問題でした。それを削除すると問題が解決しました。 –

0

、私は解決策を発見しました。

だから私のベースコントローラは、次のようになります。

abstract class ApiBaseController{ 

    @ExceptionHandler(Exception::class) 
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) 
    @ResponseBody 
    fun handleException(ex: Exception): ApiError { 
     return ApiError(ex.message) 
    } 

} 

誰もが、それはこれとない他の方法と同じように機能する理由について詳しく説明することができた場合は、そうしてくださいと認められたとして、私はあなたの答えをマークします。

関連する問題