<?php declare(strict_types=1);

namespace Amp\Http\Server;

use Amp\ByteStream\StreamException;

/**
 * A ClientException thrown from {@see RequestBody::read()} or {@see RequestBody::buffer()} indicates that the
 * requesting client stream has been closed due to an error or exceeding a server limit such as the body size limit.
 *
 * Applications may optionally catch this exception in request handlers to continue other processing. Users are NOT
 * required to catch it and if left uncaught it will simply end request handler execution. For streaming response bodies
 * in which the handler is also reading the request body, this exception should be caught and used to fail the streaming
 * response body.
 *
 * Throwing a ClientException from a request handler or failing streaming response body will abruptly
 * disconnect a client. It is not recommended to create ClientException instances in a request handler.
 *
 * Responses returned by request handlers after a ClientException has been thrown will be ignored, as a response has
 * already been generated by the error handler.
 *
 * @psalm-suppress ClassMustBeFinal
 */
class ClientException extends StreamException
{
    /** @internal Do not instantiate instances of this exception in your request handlers or middleware! */
    public function __construct(
        private readonly Driver\Client $client,
        string $message,
        int $code = 0,
        ?\Throwable $previous = null,
    ) {
        parent::__construct($message, $code, $previous);
    }

    final public function getClient(): Driver\Client
    {
        return $this->client;
    }
}
