2017-10-06 00:16:22 -05:00
< ? php
2024-03-12 22:39:16 -04:00
namespace App\Exceptions\Http\Connection ;
2017-10-06 00:16:22 -05:00
2018-01-30 20:36:59 -06:00
use Illuminate\Http\Response ;
2017-10-06 00:16:22 -05:00
use GuzzleHttp\Exception\GuzzleException ;
2024-03-12 22:39:16 -04:00
use App\Exceptions\DisplayException ;
2024-03-23 08:07:00 -04:00
use Illuminate\Support\Facades\Context ;
2017-10-06 00:16:22 -05:00
class DaemonConnectionException extends DisplayException
{
2022-10-14 10:59:20 -06:00
private int $statusCode = Response :: HTTP_GATEWAY_TIMEOUT ;
2017-12-31 10:30:19 -06:00
2021-01-17 20:51:41 -08:00
/**
2024-03-12 22:39:16 -04:00
* Every request to the daemon instance will return a unique X - Request - Id header
2021-01-17 20:51:41 -08:00
* 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 .
*/
2022-10-14 10:59:20 -06:00
private ? string $requestId ;
2021-01-17 20:51:41 -08:00
2017-10-06 00:16:22 -05:00
/**
* Throw a displayable exception caused by a daemon connection error .
*/
2020-07-18 10:23:28 -07:00
public function __construct ( GuzzleException $previous , bool $useStatusCode = true )
2017-10-06 00:16:22 -05:00
{
/** @var \GuzzleHttp\Psr7\Response|null $response */
$response = method_exists ( $previous , 'getResponse' ) ? $previous -> getResponse () : null ;
2022-10-14 10:59:20 -06:00
$this -> requestId = $response ? -> getHeaderLine ( 'X-Request-Id' );
2017-10-06 00:16:22 -05:00
2024-03-23 08:07:00 -04:00
Context :: add ( 'request_id' , $this -> requestId );
2017-12-31 10:30:19 -06:00
if ( $useStatusCode ) {
2020-08-13 21:21:08 -07:00
$this -> statusCode = is_null ( $response ) ? $this -> statusCode : $response -> getStatusCode ();
2024-03-12 22:39:16 -04:00
// There are rare conditions where daemon encounters a panic condition and crashes the
2021-04-04 10:45:33 -07:00
// 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 ;
}
2017-12-31 10:30:19 -06:00
}
2021-01-17 20:51:41 -08:00
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>' );
}
2020-08-13 21:21:08 -07:00
// Attempt to pull the actual error message off the response and return that if it is not
// a 500 level error.
2021-01-25 19:20:51 -08:00
if ( $this -> statusCode < 500 && ! is_null ( $response )) {
2021-01-17 20:51:41 -08:00
$body = json_decode ( $response -> getBody () -> __toString (), true );
2021-01-25 19:20:51 -08:00
$message = sprintf ( 'An error occurred on the remote host: %s. (request id: %s)' , $body [ 'error' ] ? ? $message , $this -> requestId ? ? '<nil>' );
2020-08-13 21:21:08 -07:00
}
$level = $this -> statusCode >= 500 && $this -> statusCode !== 504
? DisplayException :: LEVEL_ERROR
: DisplayException :: LEVEL_WARNING ;
parent :: __construct ( $message , $previous , $level );
2017-10-06 00:16:22 -05:00
}
2017-12-31 10:30:19 -06:00
/**
* Return the HTTP status code for this exception .
*/
2022-10-14 10:59:20 -06:00
public function getStatusCode () : int
2017-12-31 10:30:19 -06:00
{
return $this -> statusCode ;
}
2017-10-06 00:16:22 -05:00
}