diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php index 0a8cee3d1..65c5f5f55 100644 --- a/src/Composer/Command/DiagnoseCommand.php +++ b/src/Composer/Command/DiagnoseCommand.php @@ -224,6 +224,12 @@ EOT try { $this->httpDownloader->get($proto . '://repo.packagist.org/packages.json'); } catch (TransportException $e) { + if ($hints = HttpDownloader::getExceptionHints($e)) { + foreach ($hints as $hint) { + $result[] = $hint; + } + } + $result[] = '[' . get_class($e) . '] ' . $e->getMessage() . ''; } diff --git a/src/Composer/Console/Application.php b/src/Composer/Console/Application.php index 73779a563..192df31a0 100644 --- a/src/Composer/Console/Application.php +++ b/src/Composer/Console/Application.php @@ -30,6 +30,7 @@ use Composer\IO\IOInterface; use Composer\IO\ConsoleIO; use Composer\Json\JsonValidationException; use Composer\Util\ErrorHandler; +use Composer\Util\HttpDownloader; use Composer\EventDispatcher\ScriptExecutionException; use Composer\Exception\NoSslException; @@ -382,6 +383,12 @@ class Application extends BaseApplication $io->writeError('The following exception is caused by a lack of memory or swap, or not having swap configured', true, IOInterface::QUIET); $io->writeError('Check https://getcomposer.org/doc/articles/troubleshooting.md#proc-open-fork-failed-errors for details', true, IOInterface::QUIET); } + + if ($hints = HttpDownloader::getExceptionHints($exception)) { + foreach ($hints as $hint) { + $io->writeError($hint, true, IOInterface::QUIET); + } + } } /** diff --git a/src/Composer/Util/Http/CurlDownloader.php b/src/Composer/Util/Http/CurlDownloader.php index 8deff9f43..e5a9de423 100644 --- a/src/Composer/Util/Http/CurlDownloader.php +++ b/src/Composer/Util/Http/CurlDownloader.php @@ -157,7 +157,6 @@ class CurlDownloader curl_setopt($curlHandle, CURLOPT_URL, $url); curl_setopt($curlHandle, CURLOPT_FOLLOWLOCATION, false); - //curl_setopt($curlHandle, CURLOPT_DNS_USE_GLOBAL_CACHE, false); curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($curlHandle, CURLOPT_TIMEOUT, 300); curl_setopt($curlHandle, CURLOPT_WRITEHEADER, $headerHandle); diff --git a/src/Composer/Util/HttpDownloader.php b/src/Composer/Util/HttpDownloader.php index 8d7bc45b5..a49a806f4 100644 --- a/src/Composer/Util/HttpDownloader.php +++ b/src/Composer/Util/HttpDownloader.php @@ -378,4 +378,32 @@ class HttpDownloader $io->writeError('<'.$type.'>'.ucfirst($type).' from '.$url.': '.$data[$type].''); } } + + public static function getExceptionHints(\Exception $e) + { + if (!$e instanceof TransportException) { + return; + } + + if ( + false !== strpos($e->getMessage(), 'Resolving timed out') + || false !== strpos($e->getMessage(), 'Could not resolve host') + ) { + Silencer::suppress(); + $testConnectivity = file_get_contents('https://8.8.8.8', false, stream_context_create(array( + 'ssl' => array('verify_peer' => false), + 'http' => array('follow_location' => false, 'ignore_errors' => true) + ))); + Silencer::restore(); + if (false !== $testConnectivity) { + return array( + 'The following exception probably indicates you have misconfigured DNS resolver(s)' + ); + } + + return array( + 'The following exception probably indicates you are offline or have misconfigured DNS resolver(s)' + ); + } + } }