Added better error handling for corrupt chunks
This commit is contained in:
@@ -279,6 +279,8 @@ class RegionSet(object):
|
||||
raise Exception("Woah, what kind of dimension is this?! %r" % self.regiondir)
|
||||
|
||||
def _get_regionobj(self, regionfilename):
|
||||
# Check the cache first. If it's not there, create the
|
||||
# nbt.MCRFileReader object, cache it, and return it
|
||||
try:
|
||||
return self.regioncache[regionfilename]
|
||||
except KeyError:
|
||||
@@ -317,8 +319,36 @@ class RegionSet(object):
|
||||
if regionfile is None:
|
||||
raise ChunkDoesntExist("Chunk %s,%s doesn't exist (and neither does its region)" % (x,z))
|
||||
|
||||
region = self._get_regionobj(regionfile)
|
||||
data = region.load_chunk(x, z)
|
||||
# Try 3 times to load and parse this chunk before giving up and raising
|
||||
# an error
|
||||
tries = 5
|
||||
while True:
|
||||
try:
|
||||
region = self._get_regionobj(regionfile)
|
||||
data = region.load_chunk(x, z)
|
||||
except nbt.CorruptionError, e:
|
||||
tries -= 1
|
||||
if tries > 0:
|
||||
# Flush the region cache to possibly read a new region file
|
||||
# header
|
||||
logging.debug("Encountered a corrupt chunk at %s,%s. Flushing cache and retrying", x, z)
|
||||
logging.debug("Error was:", exc_info=1)
|
||||
del self.regioncache[regionfile]
|
||||
time.sleep(0.5)
|
||||
continue
|
||||
else:
|
||||
logging.warning("Tried %d times to read chunk %d,%d but I got error %s",
|
||||
tries, x, z, e)
|
||||
logging.debug("Full traceback:", exc_info=1)
|
||||
# Let this exception propagate out through the C code into
|
||||
# tileset.py, where it is caught and gracefully continues
|
||||
# with the next chunk
|
||||
raise
|
||||
else:
|
||||
# no exception raised: break out of the loop
|
||||
break
|
||||
|
||||
|
||||
if data is None:
|
||||
raise ChunkDoesntExist("Chunk %s,%s doesn't exist" % (x,z))
|
||||
|
||||
@@ -599,7 +629,10 @@ class CachedRegionSet(RegionSetWrapper):
|
||||
s += obj.__class__.__name__ + "."
|
||||
obj = obj._r
|
||||
# obj should now be the actual RegionSet object
|
||||
s += obj.regiondir
|
||||
try:
|
||||
s += obj.regiondir
|
||||
except AttributeError:
|
||||
s += repr(obj)
|
||||
|
||||
logging.debug("Initializing a cache with key '%s'", s)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user