BodyToMono WebClient в ожидаемом поведении пустого тела

Каково ожидаемое поведение, когда WebClient bodyToMono встречает пустое тело? В моем конкретном примере мы проверяем статус, возвращенный при вызове post, и, если это ошибка, конвертируем его в наш собственный формат ошибки. Если преобразование в настраиваемый формат ошибки не удается, мы создаем новую ошибку в нашем настраиваемом формате с указанием этого. Но когда пришел ответ, это была ошибка с пустым телом, он вообще не смог отправить ошибку, потому что bodyToMono не завершился с ошибкой, как я ожидал. См. Блок кода ниже:

.retrieve()
.onStatus(HttpStatus::isError) { response ->
    response.bodyToMono(ErrorResponse::class.java)
        .doOnError {
            throw APIException(
                code = UNEXPECTED_RESPONSE_CODE,
                reason = it.message ?: "Could not parse error response from Inventory Availability",
                httpStatus = response.statusCode()
            )
        }
        .map {
            throw APIException(
                reason = it.errors.reason,
                code = it.errors.code,
                httpStatus = response.statusCode()
            )
        }
}

Чтобы исправить это, мы добавили параметр switchIfEmpty.

.retrieve()
.onStatus(HttpStatus::isError) { response ->
    response.bodyToMono(ErrorResponse::class.java)
        .switchIfEmpty { throw RuntimeException("Received Empty Response Body") }
        .doOnError {
            throw APIException(
                code = UNEXPECTED_RESPONSE_CODE,
                reason = it.message ?: "Could not parse error response from Inventory Availability",
                httpStatus = response.statusCode()
            )
        }
        .map {
            throw APIException(
                reason = it.errors.reason,
                code = it.errors.code,
                httpStatus = response.statusCode()
            )
        }
}

У меня такой вопрос: это ожидаемое поведение от bodyToMono? Поскольку я явно прошу сопоставить тело ответа с моим объектом ErrorResponse, я бы ожидал, что пустое тело будет ошибочным, а затем ударит блок doOnError, но вместо этого он просто «преуспеет» / вернет пустой моно ... поэтому мы добавляем блок switchIfEmpty. Если бы объект, с которым мы сопоставлялись, имел поля, допускающие значение NULL, я мог бы видеть, что у него нет ошибки, но поскольку все поля необходимы, почему bodyToMono не выдает ошибку при попытке сопоставить «ничего» с моим объектом?


person chas spenlau    schedule 09.05.2019    source источник


Ответы (1)


Это правильно. Mono может создавать элементы 0..1, а пустое тело просто создает моно, которое завершается без выдачи значения, как и Mono.empty ().

Если в вашем случае нет тела ошибки, вы можете вызвать .single () в своем моно.

person Adam Bickford    schedule 02.04.2020