private async void PollForProducts(bool persistent, int delay, int retryCount = 10, bool tryLogin = false, bool loginAttempted = false, bool productsOnly = false) { await Task.Delay(delay); try { Log("Begin PollForProducts() persistent = {2}, delay = {0}, productsOnly = {1}", delay, productsOnly, persistent); var result = await DoRetrieveProducts(productsOnly); callback.OnProductListReceived(result); } catch (Exception e) { Log("PollForProducts() Exception (persistent = {0}, delay = {1}, retry = {2}), exception: {3}", persistent, delay, retryCount, e.Message); // NB: persistent here is used to distinguish when this is used by restoreTransactions() so we will // keep it intact and supplement for retries on initialization // if (persistent) { // This seems to indicate the App is not uploaded on // the dev portal, but is undocumented by Microsoft. if (e.Message.Contains("801900CC")) { Log("Exception loading listing information: {0}", e.Message); callback.OnProductListError("AppNotKnown"); // JDRjr: in the main store code this is not being checked correctly // and will result in repeated init attempts. Leaving it for now, but broken... } else if (e.Message.Contains("80070525")) { Log("PollForProducts() User not signed in error HResult = 0x{0:X} (delay = {1}, retry = {2})", e.HResult, delay, retryCount); if ((delay == 0) && (productsOnly == false)) { // First time failure give products only a try PollForProducts(true, 1000, retryCount, tryLogin, loginAttempted, true); } else { // Gonna call this an error Log("Calling OnProductListError() delay = {0}, productsOnly = {1}", delay, productsOnly); callback.OnProductListError("801900CC because the C# code is broken"); } } else { // other (no special handling) error codes // Wait up to 5 mins. // JDRjr: this seems like too long... delay = Math.Max(5000, delay); var newDelay = Math.Min(300000, delay * 2); PollForProducts(true, newDelay); } } else { Log("Polling for products exception: {0}", e.Message); // This is a restore attempt that has thrown an exception // We should allow for a login attempt here as well... if (tryLogin == true) { Log("Attempting Windows Store login from within IAP"); var uri = new Uri("ms-windows-store://signin"); var loginResult = await global::Windows.System.Launcher.LaunchUriAsync(uri); PollForProducts(true, 1000, retryCount, false, true, false); } else { if (retryCount > 0) { if (loginAttempted) { Log("Waiting {0}", retryCount); // Will wait for retryCount seconds... PollForProducts(true, 1000, --retryCount, false, true); } else { // Wait up to 5 mins. delay = Math.Max(5000, delay); var newDelay = Math.Min(300000, delay * 2); PollForProducts(true, newDelay, --retryCount, false, false); } } else { Log("Calling OnProductListError()"); callback.OnProductListError("801900CC because the C# code is broken"); } } } } // end of catch() }