diff --git a/app/Exceptions/Http/Connection/DaemonConnectionException.php b/app/Exceptions/Http/Connection/DaemonConnectionException.php index e6765b8a6..138a665c3 100644 --- a/app/Exceptions/Http/Connection/DaemonConnectionException.php +++ b/app/Exceptions/Http/Connection/DaemonConnectionException.php @@ -2,8 +2,8 @@ namespace Pterodactyl\Exceptions\Http\Connection; -use Illuminate\Support\Arr; use Illuminate\Http\Response; +use Illuminate\Support\Facades\Log; use GuzzleHttp\Exception\GuzzleException; use Pterodactyl\Exceptions\DisplayException; @@ -17,6 +17,16 @@ class DaemonConnectionException extends DisplayException */ private $statusCode = Response::HTTP_GATEWAY_TIMEOUT; + /** + * Every request to the Wings 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. + * + * @var string|null + */ + private $requestId; + /** * Throw a displayable exception caused by a daemon connection error. * @@ -27,23 +37,23 @@ class DaemonConnectionException extends DisplayException { /** @var \GuzzleHttp\Psr7\Response|null $response */ $response = method_exists($previous, 'getResponse') ? $previous->getResponse() : null; + $this->requestId = $response ? $response->getHeaderLine('X-Request-Id') : null; if ($useStatusCode) { $this->statusCode = is_null($response) ? $this->statusCode : $response->getStatusCode(); } - $message = trans('admin/server.exceptions.daemon_exception', [ - 'code' => is_null($response) ? 'E_CONN_REFUSED' : $response->getStatusCode(), - ]); + 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 ?? ''); + } // 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 = $response->getBody(); - if (is_string($body) || (is_object($body) && method_exists($body, '__toString'))) { - $body = json_decode(is_string($body) ? $body : $body->__toString(), true); - $message = "[Wings Error]: " . Arr::get($body, 'error', $message); - } + $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 ?? ''); } $level = $this->statusCode >= 500 && $this->statusCode !== 504 @@ -53,6 +63,19 @@ class DaemonConnectionException extends DisplayException parent::__construct($message, $previous, $level); } + /** + * Override the default reporting method for DisplayException by just logging immediately + * here and including the specific X-Request-Id header that was returned by the call. + * + * @return void + */ + public function report() + { + Log::{$this->getErrorLevel()}($this->getPrevious(), [ + 'request_id' => $this->requestId, + ]); + } + /** * Return the HTTP status code for this exception. * @@ -62,4 +85,12 @@ class DaemonConnectionException extends DisplayException { return $this->statusCode; } + + /** + * @return string|null + */ + public function getRequestId() + { + return $this->requestId; + } } diff --git a/resources/lang/en/admin/server.php b/resources/lang/en/admin/server.php index a697d4e9e..3a9d57f9d 100644 --- a/resources/lang/en/admin/server.php +++ b/resources/lang/en/admin/server.php @@ -12,7 +12,7 @@ return [ 'no_new_default_allocation' => 'You are attempting to delete the default allocation for this server but there is no fallback allocation to use.', 'marked_as_failed' => 'This server was marked as having failed a previous installation. Current status cannot be toggled in this state.', 'bad_variable' => 'There was a validation error with the :name variable.', - 'daemon_exception' => 'There was an exception while attempting to communicate with the daemon resulting in a HTTP/:code response code. This exception has been logged.', + 'daemon_exception' => 'There was an exception while attempting to communicate with the daemon resulting in a HTTP/:code response code. This exception has been logged. (request id: :request_id)', 'default_allocation_not_found' => 'The requested default allocation was not found in this server\'s allocations.', ], 'alerts' => [