mirror of
				https://github.com/pelican-dev/panel.git
				synced 2025-11-04 15:26:51 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			77 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace App\Exceptions\Http\Connection;
 | 
						|
 | 
						|
use Illuminate\Http\Response;
 | 
						|
use GuzzleHttp\Exception\GuzzleException;
 | 
						|
use App\Exceptions\DisplayException;
 | 
						|
use Illuminate\Support\Facades\Context;
 | 
						|
 | 
						|
/**
 | 
						|
 * @method \GuzzleHttp\Exception\GuzzleException getPrevious()
 | 
						|
 */
 | 
						|
class DaemonConnectionException extends DisplayException
 | 
						|
{
 | 
						|
    private int $statusCode = Response::HTTP_GATEWAY_TIMEOUT;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Every request to the daemon instance will return a unique X-Request-Id header
 | 
						|
     * which allows for all errors to be efficiently tied to a specific request that
 | 
						|
     * triggered them, and gives users a more direct method of informing hosts when
 | 
						|
     * something goes wrong.
 | 
						|
     */
 | 
						|
    private ?string $requestId;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Throw a displayable exception caused by a daemon connection error.
 | 
						|
     */
 | 
						|
    public function __construct(GuzzleException $previous, bool $useStatusCode = true)
 | 
						|
    {
 | 
						|
        /** @var \GuzzleHttp\Psr7\Response|null $response */
 | 
						|
        $response = method_exists($previous, 'getResponse') ? $previous->getResponse() : null;
 | 
						|
        $this->requestId = $response?->getHeaderLine('X-Request-Id');
 | 
						|
 | 
						|
        Context::add('request_id', $this->requestId);
 | 
						|
 | 
						|
        if ($useStatusCode) {
 | 
						|
            $this->statusCode = is_null($response) ? $this->statusCode : $response->getStatusCode();
 | 
						|
            // There are rare conditions where daemon encounters a panic condition and crashes the
 | 
						|
            // request being made after content has already been sent over the wire. In these cases
 | 
						|
            // you can end up with a "successful" response code that is actual an error.
 | 
						|
            //
 | 
						|
            // Handle those better here since we shouldn't ever end up in this exception state and
 | 
						|
            // be returning a 2XX level response.
 | 
						|
            if ($this->statusCode < 400) {
 | 
						|
                $this->statusCode = Response::HTTP_BAD_GATEWAY;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (is_null($response)) {
 | 
						|
            $message = 'Could not establish a connection to the machine running this server. Please try again.';
 | 
						|
        } else {
 | 
						|
            $message = sprintf('There was an error while communicating with the machine running this server. This error has been logged, please try again. (code: %s) (request_id: %s)', $response->getStatusCode(), $this->requestId ?? '<nil>');
 | 
						|
        }
 | 
						|
 | 
						|
        // Attempt to pull the actual error message off the response and return that if it is not
 | 
						|
        // a 500 level error.
 | 
						|
        if ($this->statusCode < 500 && !is_null($response)) {
 | 
						|
            $body = json_decode($response->getBody()->__toString(), true);
 | 
						|
            $message = sprintf('An error occurred on the remote host: %s. (request id: %s)', $body['error'] ?? $message, $this->requestId ?? '<nil>');
 | 
						|
        }
 | 
						|
 | 
						|
        $level = $this->statusCode >= 500 && $this->statusCode !== 504
 | 
						|
            ? DisplayException::LEVEL_ERROR
 | 
						|
            : DisplayException::LEVEL_WARNING;
 | 
						|
 | 
						|
        parent::__construct($message, $previous, $level);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the HTTP status code for this exception.
 | 
						|
     */
 | 
						|
    public function getStatusCode(): int
 | 
						|
    {
 | 
						|
        return $this->statusCode;
 | 
						|
    }
 | 
						|
}
 |