/**
  * Convert a ClientKeyBlock to a Bucket. If an error occurs, report it via onFailure and return
  * null.
  */
 protected Bucket extract(
     ClientKeyBlock block, Object token, ObjectContainer container, ClientContext context) {
   Bucket data;
   try {
     data =
         block.decode(
             context.getBucketFactory(persistent),
             (int) (Math.min(ctx.maxOutputLength, Integer.MAX_VALUE)),
             false);
   } catch (KeyDecodeException e1) {
     if (Logger.shouldLog(Logger.MINOR, this)) Logger.minor(this, "Decode failure: " + e1, e1);
     onFailure(
         new FetchException(FetchException.BLOCK_DECODE_ERROR, e1.getMessage()),
         token,
         container,
         context);
     return null;
   } catch (TooBigException e) {
     onFailure(
         new FetchException(FetchException.TOO_BIG, e.getMessage()), token, container, context);
     return null;
   } catch (IOException e) {
     Logger.error(this, "Could not capture data - disk full?: " + e, e);
     onFailure(new FetchException(FetchException.BUCKET_ERROR, e), token, container, context);
     return null;
   }
   if (Logger.shouldLog(Logger.MINOR, this))
     Logger.minor(
         this, data == null ? "Could not decode: null" : ("Decoded " + data.size() + " bytes"));
   return data;
 }