private async Task <bool> ProcessPackage(UserInfo userInfo, string feedName, PackageName packageName, PackageState packageState, PackageState damagedPackageState, Func <IPackageStorageItem, Task <IPackageStorageItem> > tryWithPackageItemBefore, Func <IPackageStorageItem, ZipPackage, Task> tryWithPackage, Func <IPackageStorageItem, Task> tryWithPackageItemAfter) { var feed = storage.GetFeed(feedName); var packageItem = feed.GetPackage(null, packageState, packageName); var traceName = packageItem.ToString(); try { packageItem = await tryWithPackageItemBefore(packageItem); if (packageItem == null) { throw new Exception(string.Format("Missing package {0}", traceName)); } using (var packageStream = await packageItem.Get()) { if (packageStream == null) { throw new Exception(string.Format("Missing package data {0}", traceName)); } var package = new ZipPackage(packageStream); await tryWithPackage(packageItem, package); } await tryWithPackageItemAfter(packageItem); return(true); } catch (Exception e) { support.TrackException(e, new { packageName }); Trace.TraceError("Unexpected error while processing package {0}:\n{1}", traceName, e); notifier.Damaged(userInfo, packageName).Wait(); if (packageItem != null) { packageItem.Move(damagedPackageState, packageName).Wait(); } return(false); } }