티스토리 뷰
반응형
리액티브 마이크로서비스를 만들 때 어떤 오류도 정상적으로 처리해야 됩니다.
따라서 리액터 프레임워크는 이런 오류를 처리하기 위한 메커니즘을 제공합니다.
핸들러에서 오류 찾기
핸들러를 만들 때 오류가 발생할 수 있으며 이런 오류는 리액티브 게시자 onErrorResume에서 특별한 방법으로 처리 가능합니다.
@Component
class CustomerHandler(private val customerService: CustomerService) {
...
fun create(serverRequest: ServerRequest) =
customerService.createCustomer(serverRequest.bodyToMono()).flatMap {
created(URI.create("/functional/customer/${it.id}")).build()
}.onErrorResume(Exception::class) {
badRequest().body(fromObject("400 BAD REQUEST"))
}
}
onErrorResume을 사용해 오류가 발생하면 해당 오류를 처리할 수 있다는 것을 모든 리액티브 게시자에게 알릴 수 있습니다. 위에서는 람다식으로 코드를 작성하였습니다.
잘못된 Body 값을 POST로 보내면 아래와 같은 응답을 얻을 수 있습니다.
400 BAD REQUEST
Error에 대해 JSON 응답을 하는 data class를 만들었습니다.
data class ErrorResponse(
val error: String,
val message: String
)
그리고 아래와 같이 적용하였습니다.
@Component
class CustomerHandler(private val customerService: CustomerService) {
...
fun create(serverRequest: ServerRequest) =
customerService.createCustomer(serverRequest.bodyToMono()).flatMap {
//status(HttpStatus.CREATED).body(fromObject(it))
created(URI.create("/functional/customer/${it.id}")).build()
}.onErrorResume(Exception::class) {
badRequest().body(fromObject(ErrorResponse("400 BAD REQUEST", it.message ?: "error")))
}
}
위와 같이 잘못된 Body 값을 POST로 보내면 아래와 같은 응답을 얻을 수 있습니다.
{
"error": "400 BAD REQUEST",
"message": "400 BAD_REQUEST \"Failed to read HTTP message\"; nested exception is org.springframework.core.codec.DecodingException: JSON decoding error: Unexpected character ('}' (code 125)): was expecting double-quote to start field name; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('}' (code 125)): was expecting double-quote to start field name\n at [Source: (io.netty.buffer.ByteBufInputStream); line: 7, column: 6] (through reference chain: com.imtae.chapter4.Customer[\"telephone\"])"
}
오류 게시
이미 생성된 고객을 또 생성하려고 하면 오류를 발생해야 됩니다.
아래와 같이 CustomExistException 클래스를 만들었습니다.
class CustomerExistException(override val message: String) : Exception(message)
그리고 ServiceImpl 클래스의 함수를 아래와 같이 수정하였습니다.
@Component
class CustomerServiceImpl : CustomerService {
...
override fun createCustomer(customerMono: Mono<Customer>) =
customerMono.flatMap {
if (customers[it.id] == null) {
customers[it.id] = it
it.toMono()
} else {
Mono.error(CustomerExistException("${it.id}번째 고객이 이미 있습니다."))
}
}
}
고객이 존재하는지 확인을 하고, 존재하지 않을 경우 저장하고 Mono로 반환합니다.
고객이 없다면 Mono.error를 통해 오류를 포함하는 Mono를 생성합니다.
두 번째 요청 시 아래와 같은 응답을 받습니다.
{
"error": "400 BAD REQUEST",
"message": "4번째 고객이 이미 있습니다."
}
반응형
'알려주는 이야기 > 스프링 부트' 카테고리의 다른 글
Spring Boot - MongoDB [ 프로젝트 세팅 ] (0) | 2020.09.16 |
---|---|
Spring Boot - MongoDB [ 설치 및 사용 방법 ] (0) | 2020.09.16 |
Spring Boot - Reative Rest Api [ 함수형 ] (0) | 2020.09.09 |
Spring Boot - Reative Rest Api [ 리액티브 서비스 ] (0) | 2020.09.09 |
Spring Boot - Reative Rest Api [ 스프링 웹플럭스 ] (1) | 2020.09.08 |
댓글