From d8c9c3dc995d0df318eb57b0e2248b8a5a04ea9c Mon Sep 17 00:00:00 2001
From: Zooko O'Whielacronx <zooko@zooko.com>
Date: Fri, 2 Jan 2009 12:58:58 -0700
Subject: [PATCH] immutable: download.py: Raise the appropriate type of
 exception to indicate the cause of failure, e.g. BadOrMissingHash,
 ServerFailure, IntegrityCheckReject (which is a supertype of
 BadOrMissingHash).  This helps users (such as verifier/repairer) catch
 certain classes of reasons for "why did this download not work".  The tests
 of verifier/repairer test this code and rely on this code.

---
 src/allmydata/immutable/download.py | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/allmydata/immutable/download.py b/src/allmydata/immutable/download.py
index ce40ba92..fda9ef2a 100644
--- a/src/allmydata/immutable/download.py
+++ b/src/allmydata/immutable/download.py
@@ -9,6 +9,7 @@ from foolscap.eventual import eventually
 
 from allmydata.util import base32, mathutil, hashutil, log
 from allmydata.util.assertutil import _assert, precondition
+from allmydata.util.rrefutil import ServerFailure
 from allmydata import codec, hashtree, uri
 from allmydata.interfaces import IDownloadTarget, IDownloader, IFileURI, IVerifierURI, \
      IDownloadStatus, IDownloadResults, IValidatedThingProxy, NotEnoughSharesError
@@ -162,7 +163,7 @@ class ValidatedCrypttextHashTreeProxy:
         except (hashtree.BadHashError, hashtree.NotEnoughHashesError), le:
             if self._fetch_failures is not None:
                 self._fetch_failures["crypttext_hash_tree"] += 1
-            raise
+            raise BadOrMissingHash(le)
         return self
 
     def start(self):
@@ -494,8 +495,12 @@ class BlockDownloader(log.PrefixingLogMixin):
         self.parent.hold_block(self.blocknum, data)
 
     def _got_block_error(self, f):
-        failtype = f.trap(DeadReferenceError, IntegrityCheckReject)
-        self.log("failure to get block", level=log.UNUSUAL, umid="5Z4uHQ")
+        failtype = f.trap(ServerFailure, IntegrityCheckReject, layout.LayoutInvalid)
+        if f.check(ServerFailure):
+            level = log.UNUSUAL
+        else:
+            level = log.WEIRD
+        self.log("failure to get block", level=level, umid="5Z4uHQ")
         if self.results:
             peerid = self.vbucket.bucket.get_peerid()
             self.results.server_problems[peerid] = str(f)
-- 
2.45.2