diff --git a/VOffline/Services/Vk/VkApiUtils.cs b/VOffline/Services/Vk/VkApiUtils.cs index 6724c7a..0f86319 100644 --- a/VOffline/Services/Vk/VkApiUtils.cs +++ b/VOffline/Services/Vk/VkApiUtils.cs @@ -153,10 +153,21 @@ namespace VOffline.Services.Vk .Select(pageNumber => (ulong)pageNumber * pageSize) .Select(async offset => { - var page = await pageGetter(pageSize, offset); - log.Debug($"{0}/{total}, {page.Count} items"); + VkCollection page = null; + try + { + page = await pageGetter(pageSize, offset); + log.Debug($"{offset}/{total}, {page.Count} items"); + } + catch (Exception e) + { + log.Warn($"Error getting page {offset}/{total}. Getting page by smaller chunks...", e); + var items = await GetSinglePage(pageGetter, offset, pageSize, token, log); + page = new VkCollection(0, items); + } + token.ThrowIfCancellationRequested(); - return page; + return page ?? new VkCollection(0, new List()); }); var pages = await Task.WhenAll(pageTasks); foreach (var page in pages) @@ -177,6 +188,29 @@ namespace VOffline.Services.Vk return result.ToList(); } + private async Task> GetSinglePage(PageGetter pageGetter, decimal offset, decimal length, CancellationToken token, ILog log) + { + var pageTasks = Enumerable.Range((int)offset, (int)length) + .Select(async x => + { + VkCollection page = null; + try + { + page = await pageGetter(1, offset); + log.Debug($"{x}/{length} item from bad page"); + } + catch (Exception e) + { + log.Warn($"Error getting item {x}", e); + } + + token.ThrowIfCancellationRequested(); + return page ?? new VkCollection(0, new List()); + }); + var pages = await Task.WhenAll(pageTasks); + return pages.SelectMany(x => x); + } + public async Task ExpandPlaylist(AudioPlaylist playlist, CancellationToken token, ILog log) { var audios = await GetAllPagesAsync(AudiosInPlaylist(playlist), long.MaxValue, token, log, true);