From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35445) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cyp5p-0004ui-RL for guix-patches@gnu.org; Thu, 13 Apr 2017 20:28:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cyp5m-0005Ox-Mz for guix-patches@gnu.org; Thu, 13 Apr 2017 20:28:05 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:48059) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cyp5m-0005Oo-JI for guix-patches@gnu.org; Thu, 13 Apr 2017 20:28:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1cyp5m-00045a-BP for guix-patches@gnu.org; Thu, 13 Apr 2017 20:28:02 -0400 Subject: bug#26489: [PATCH] substitute: Ignore bad responses. Resent-Message-ID: Received: from eggs.gnu.org ([2001:4830:134:3::10]:35291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cyp4q-0004rD-6r for guix-patches@gnu.org; Thu, 13 Apr 2017 20:27:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cyp4n-00058B-1l for guix-patches@gnu.org; Thu, 13 Apr 2017 20:27:04 -0400 Received: from relay2-d.mail.gandi.net ([217.70.183.194]:58022) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cyp4m-00057g-Sn for guix-patches@gnu.org; Thu, 13 Apr 2017 20:27:00 -0400 Received: from mfilter14-d.gandi.net (mfilter14-d.gandi.net [217.70.178.142]) by relay2-d.mail.gandi.net (Postfix) with ESMTP id CC644C5A54 for ; Fri, 14 Apr 2017 02:26:57 +0200 (CEST) Received: from relay2-d.mail.gandi.net ([IPv6:::ffff:217.70.183.194]) by mfilter14-d.gandi.net (mfilter14-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id hW0WwWkSp0z1 for ; Fri, 14 Apr 2017 02:26:56 +0200 (CEST) Received: from v5.tobias.gr (34.210-240-81.adsl-dyn.isp.belgacom.be [81.240.210.34]) (Authenticated sender: me@tobias.gr) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 501F4C5A50 for ; Fri, 14 Apr 2017 02:26:55 +0200 (CEST) From: Tobias Geerinckx-Rice Date: Fri, 14 Apr 2017 02:27:55 +0200 Message-Id: <20170414002755.32672-1-me@tobias.gr> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+kyle=kyleam.com@gnu.org Sender: "Guix-patches" To: 26489@debbugs.gnu.org * guix/scripts/substitute.scm (http-multiple-get): Catch BAD-RESPONSE exceptions and keep going. --- Guix, One weird HTTP response from a server will kill ‘guix substitute’: updating list of substitutes from 'https://foo'... 50.0%Backtrace: ... guix/ui.scm:1229:8: In procedure run-guix-command: guix/ui.scm:1229:8: Throw to key `bad-response' with args `("Bad Response-Line: ~s" (""))'. error: build failed: substituter `substitute' died unexpectedly Attached is a patch to ignore such bad responses. The offending .narinfo will be ignored for that session, and not cached at all. The result: updating list of substitutes from 'https://bar'... 100.0% updating list of substitutes from 'https://foo'... 2.9% (bad response) updating list of substitutes from 'https://foo'... 5.9% (bad response) As a nice bonus, guix doesn't keel over and die. Is this the best solution? A good one? Should it be made more obvious that only READ-RESPONSE can throw, and that PROC will never be called with, a bad response? No idea. I haven't had enough free time to learn good the Guile like I'd so hoped to do at the beginning of the year. :c Be gentle, dear reader, and all that, T G-R guix/scripts/substitute.scm | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm index d3bccf4dd..7eccf9831 100755 --- a/guix/scripts/substitute.scm +++ b/guix/scripts/substitute.scm @@ -564,18 +564,24 @@ initial connection on which HTTP requests are sent." (() (reverse result)) ((head tail ...) - (let* ((resp (read-response p)) - (body (response-body-port resp)) - (result (proc head resp body result))) - ;; The server can choose to stop responding at any time, in which - ;; case we have to try again. Check whether that is the case. - ;; Note that even upon "Connection: close", we can read from BODY. - (match (assq 'connection (response-headers resp)) - (('connection 'close) - (close-connection p) - (connect #f tail result)) ;try again - (_ - (loop tail result)))))))))) ;keep going + (catch 'bad-response + (lambda () + (let* ((resp (read-response p)) + (body (response-body-port resp)) + (result (proc head resp body result))) + ;; The server can stop responding at any time, in which case + ;; we have to try again. Check whether that's the case. Note + ;; that we can read from BODY even upon "Connection: close". + (match (assq 'connection (response-headers resp)) + (('connection 'close) + (close-connection p) + (connect #f tail result)) ; try again + (_ + (loop tail result))))) ; keep going + (lambda args + ;; This message appears on the same line as the progress report. + (format (current-error-port) " (bad response)~%") + (loop tail result))))))))) ; keep going (define (read-to-eof port) "Read from PORT until EOF is reached. The data are discarded." -- 2.12.2