Repository: ktorio/ktor
File: ktor-client/ktor-client-core/common/src/io/ktor/client/plugins/HttpCallValidator.kt (Kotlin)

Code before:
     * Last added validator executes first.
     */
    public fun validateResponse(block: ResponseValidator) {
        responseValidators += block
    }
}

/**
 * Response validator method.
 *
 * You could throw an exception to fail the response.
 */
public typealias ResponseValidator = suspend (response: HttpResponse) -> Unit

/**
 * Response exception handler method.
 */
public typealias CallExceptionHandler = suspend (cause: Throwable) -> Unit

/**
 * Response exception handler method. [request] is null if
 */
public typealias CallRequestExceptionHandler = suspend (cause: Throwable, request: HttpRequest) -> Unit

/**
 * Response validator plugin is used for validating [HttpClient] response and handle response exceptions.
 *
 * See also [HttpCallValidatorConfig] for additional details.
 */
public val HttpCallValidator: ClientPlugin<HttpCallValidatorConfig> = createClientPlugin(
    "HttpResponseValidator",
    ::HttpCallValidatorConfig
) {

    val responseValidators: List<ResponseValidator> = pluginConfig.responseValidators.reversed()
    val callExceptionHandlers: List<HandlerWrapper> = pluginConfig.responseExceptionHandlers.reversed()

    val expectSuccess: Boolean = pluginConfig.expectSuccess

    suspend fun validateResponse(response: HttpResponse) {
        LOGGER.trace("Validating response for request ${response.call.request.url}")
        responseValidators.forEach { it(response) }
    }

    suspend fun processException(cause: Throwable, request: HttpRequest) {
        LOGGER.trace("Processing exception $cause for request ${request.url}")
        callExceptionHandlers.forEach {
            when (it) {
                is ExceptionHandlerWrapper -> it.handler(cause)
                is RequestExceptionHandlerWrapper -> it.handler(cause, request)
            }

Review comment (suggestion):
```suggestion
 * The response validator plugin is used for validating an [HttpClient] response and handling response exceptions.
```

Code after:
     * Last added validator executes first.
     */
    public fun validateResponse(block: ResponseValidator) {
        responseValidators += block
    }
}

/**
 * Response validator method.
 *
 * You could throw an exception to fail the response.
 */
public typealias ResponseValidator = suspend (response: HttpResponse) -> Unit

/**
 * Response exception handler method.
 */
public typealias CallExceptionHandler = suspend (cause: Throwable) -> Unit

/**
 * Response exception handler method. [request] is null if
 */
public typealias CallRequestExceptionHandler = suspend (cause: Throwable, request: HttpRequest) -> Unit

/**
 * The response validator plugin is used for validating an [HttpClient] response and handling response exceptions.
 *
 * For more details, see [HttpCallValidatorConfig].
 */
public val HttpCallValidator: ClientPlugin<HttpCallValidatorConfig> = createClientPlugin(
    "HttpResponseValidator",
    ::HttpCallValidatorConfig
) {

    val responseValidators: List<ResponseValidator> = pluginConfig.responseValidators.reversed()
    val callExceptionHandlers: List<HandlerWrapper> = pluginConfig.responseExceptionHandlers.reversed()

    val expectSuccess: Boolean = pluginConfig.expectSuccess

    suspend fun validateResponse(response: HttpResponse) {
        LOGGER.trace("Validating response for request ${response.call.request.url}")
        responseValidators.forEach { it(response) }
    }

    suspend fun processException(cause: Throwable, request: HttpRequest) {
        LOGGER.trace("Processing exception $cause for request ${request.url}")
        callExceptionHandlers.forEach {
            when (it) {
                is ExceptionHandlerWrapper -> it.handler(cause)
                is RequestExceptionHandlerWrapper -> it.handler(cause, request)
            }