diff --git a/src/main/kotlin/no/nb/mlt/wls/core/data/synq/SynqError.kt b/src/main/kotlin/no/nb/mlt/wls/core/data/synq/SynqError.kt index ab184982..36ab98df 100644 --- a/src/main/kotlin/no/nb/mlt/wls/core/data/synq/SynqError.kt +++ b/src/main/kotlin/no/nb/mlt/wls/core/data/synq/SynqError.kt @@ -1,3 +1,27 @@ package no.nb.mlt.wls.core.data.synq -data class SynqError(val errorCode: Int, val errorText: String) +import org.springframework.web.reactive.function.client.WebClientResponseException +import org.springframework.web.server.ServerErrorException + +data class SynqError(val errorCode: Int, val errorText: String) { + companion object { + /** + * Converts a WebClient error into a ServerErrorException. + * This is used for propagating error data to the client. + * @see ServerErrorException + * @see no.nb.mlt.wls.order.service.SynqOrderService + * @see no.nb.mlt.wls.product.service.SynqProductService + */ + fun createServerError(error: WebClientResponseException): ServerErrorException { + val errorBody = error.getResponseBodyAs(SynqError::class.java) + + return ServerErrorException( + "Failed to create product in SynQ, the storage system responded with error code: " + + "'${errorBody?.errorCode ?: "NO ERROR CODE FOUND"}' " + + "and error text: " + + "'${errorBody?.errorText ?: "NO ERROR TEXT FOUND"}'", + error + ) + } + } +} diff --git a/src/main/kotlin/no/nb/mlt/wls/order/service/SynqOrderService.kt b/src/main/kotlin/no/nb/mlt/wls/order/service/SynqOrderService.kt index cbb6533d..12a6a446 100644 --- a/src/main/kotlin/no/nb/mlt/wls/order/service/SynqOrderService.kt +++ b/src/main/kotlin/no/nb/mlt/wls/order/service/SynqOrderService.kt @@ -1,17 +1,17 @@ package no.nb.mlt.wls.order.service +import kotlinx.coroutines.reactor.awaitSingle import no.nb.mlt.wls.core.data.synq.SynqError +import no.nb.mlt.wls.core.data.synq.SynqError.Companion.createServerError import no.nb.mlt.wls.order.payloads.SynqOrder import no.nb.mlt.wls.order.payloads.SynqOrderPayload import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value -import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.stereotype.Service -import org.springframework.web.client.HttpClientErrorException import org.springframework.web.reactive.function.BodyInserters import org.springframework.web.reactive.function.client.WebClient -import org.springframework.web.server.ServerErrorException +import org.springframework.web.reactive.function.client.WebClientResponseException import java.net.URI @Service @@ -21,33 +21,21 @@ class SynqOrderService( @Value("\${synq.path.base}") lateinit var baseUrl: String - fun createOrder(payload: SynqOrderPayload): ResponseEntity { + suspend fun createOrder(payload: SynqOrderPayload): ResponseEntity { val uri = URI.create("$baseUrl/orders/batch") // Wrap the order in the way SynQ likes it val orders = SynqOrder(listOf(payload)) - try { - return ResponseEntity( - webClient - .post() - .uri(uri) - .body(BodyInserters.fromValue(orders)) - .retrieve() - .bodyToMono(SynqError::class.java) - .block(), - HttpStatus.CREATED - ) - } catch (exception: HttpClientErrorException) { - val errorBody = exception.getResponseBodyAs(SynqError::class.java) - - throw ServerErrorException( - "Failed to create product in SynQ, the storage system responded with error code: " + - "'${errorBody?.errorCode ?: "NO ERROR CODE FOUND"}' " + - "and error text: " + - "'${errorBody?.errorText ?: "NO ERROR TEXT FOUND"}'", - exception - ) - } + return webClient + .post() + .uri(uri) + .body(BodyInserters.fromValue(orders)) + .retrieve() + .toEntity(SynqError::class.java) + .onErrorMap(WebClientResponseException::class.java) { + createServerError(it) + } + .awaitSingle() } } diff --git a/src/main/kotlin/no/nb/mlt/wls/product/service/SynqProductService.kt b/src/main/kotlin/no/nb/mlt/wls/product/service/SynqProductService.kt index 71df9e12..79a8429f 100644 --- a/src/main/kotlin/no/nb/mlt/wls/product/service/SynqProductService.kt +++ b/src/main/kotlin/no/nb/mlt/wls/product/service/SynqProductService.kt @@ -2,6 +2,7 @@ package no.nb.mlt.wls.product.service import kotlinx.coroutines.reactor.awaitSingle import no.nb.mlt.wls.core.data.synq.SynqError +import no.nb.mlt.wls.core.data.synq.SynqError.Companion.createServerError import no.nb.mlt.wls.product.payloads.SynqProductPayload import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value @@ -38,22 +39,10 @@ class SynqProductService( Mono.error(error) } } - .onErrorMap(WebClientResponseException::class.java) { transformSynqError(it) } + .onErrorMap(WebClientResponseException::class.java) { createServerError(it) } .onErrorReturn(DuplicateProductException::class.java, ResponseEntity.ok().build()) .awaitSingle() } - - fun transformSynqError(error: WebClientResponseException): ServerErrorException { - val errorBody = error.getResponseBodyAs(SynqError::class.java) - - return ServerErrorException( - "Failed to create product in SynQ, the storage system responded with error code: " + - "'${errorBody?.errorCode ?: "NO ERROR CODE FOUND"}' " + - "and error text: " + - "'${errorBody?.errorText ?: "NO ERROR TEXT FOUND"}'", - error - ) - } } class DuplicateProductException(override val cause: Throwable) : ServerErrorException("Product already exists in SynQ", cause)