anchor.diff:        return _saveDatabase();
       })
       .then((_) {
  -      completer.complete(_);
  +      completer.complete(true);
  +    })
  +    .catchError((e, trace) {
  +      PinUtility.handleError(e, trace);
  +      completer.completeError(e, trace);
       });
   
       return completer.future;
     }
   
     Future removeCategory(String uuid) {
  -    final completer = new Completer();
  -
  -    // validate uuid
  -    if (!PinUtility.isUuid(uuid)) {
  -      PinLogger.instance.shout('[CartModel] removeCategory: uuid format invalid: ${uuid}}');
  -      completer.complete(null);
  -    }
  -
  -    CartCategory category = categories.find(uuid);
  -    if (category == null) {
  -      PinLogger.instance.warning('[CartModel] removeCategory: Category not found, uuid: ${uuid}');
  -      completer.complete(null);
  -    }
  -
  -    categories.remove(uuid, posts, tags);
  +    CartCategory category = null;
  +
  +    try {
  +      // validate uuid
  +      if (!PinUtility.isUuid(uuid)) {
  +        throw new Exception('[CartModel] removeCategory: uuid format invalid: ${uuid}}');
  +      }
  +      category = categories.find(uuid);
  +      if (category == null) {
  +        throw new Exception('[CartModel] removeCategory: Category not found, uuid: ${uuid}');
  +      }
  +      categories.remove(uuid, posts, tags);
  +    } catch (e, trace) {
  +      PinUtility.handleError(e, trace);
  +      return new Future.error(e, trace);
  +    }
  +
  +    final completer = new Completer();
   
       _drive.drive_trash(category.driveId)
       .then((GoogleDriveClient.File file) {
         return _saveDatabase();
       })
       .then((_) {
  -      completer.complete(_);
  +      completer.complete(true);
  +    })
  +    .catchError((e, trace) {
  +      PinUtility.handleError(e, trace);
  +      completer.completeError(e, trace);
       });
   
       return completer.future;
  
positive.code:     posts.add(post);
  
      // save db files & create html file & sync with google drive
      _saveDatabase().then((_) {
        _uploadPost(post, markdown, html).then((_) {
          completer.complete();
        });
      });
  
      return completer.future;
  
negative.code:         PinGoogleDrive.qIsRootFiles,
          PinGoogleDrive.qIsFolder,
          "title = '${rootFolderName}'"
      ])
      .then((GoogleDriveClient.FileList files) {
        if (files.items.length <= 0) {
          // no necessary root blog folder, create it
          return _drive.drive_folder(rootFolderName);
        } else {
          return new Future.value(files.items.removeAt(0)); // shall only contains 1 item
        }
      })
      .then((GoogleDriveClient.File file) {
        completer.complete(file.id);
      })
      .catchError((e, trace) {
        PinUtility.handleError(e, trace);
        completer.completeError(e, trace);
      });
  
      return completer.future;
  