Better handle network error when fetching sublist

Reported internally:

> STR --
>
> Import https://cdn.statically.io/gh/uBlockOrigin/uAssets/master/filters/filters.txt
> as a Custom filter list.
>
> Observe the filter count at 24K instead of true count
> being 29K.
>
> Force updating is sometimes compiling 24K filters and
> on subsequent updates 29K, so I narrowed it down to
> this host.

Findings:

One of the sublists was erroring when being fetched on
this particular CDN server (reason unknown).

uBO was not properly handling network errors when
fetching a sublist. This commit make it so that if
a sublist can't be fetched, then the error is propagated
as if it affected the whole list, in which case uBO will
use an alternative URL if any.
This commit is contained in:
Raymond Hill 2021-04-29 08:32:32 -04:00
parent 4d12ae1387
commit fca4db8021
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 15 additions and 4 deletions

View File

@ -245,6 +245,8 @@ api.fetchFilterList = async function(mainlistURL) {
const sublistURLs = new Set();
// https://github.com/uBlockOrigin/uBlock-issues/issues/1113
// Process only `!#include` directives which are not excluded by an
// `!#if` directive.
const processIncludeDirectives = function(results) {
const out = [];
const reInclude = /^!#include +(\S+)/gm;
@ -297,10 +299,19 @@ api.fetchFilterList = async function(mainlistURL) {
let allParts = [
this.fetchText(mainlistURL)
];
for (;;) {
allParts = processIncludeDirectives(await Promise.all(allParts));
if ( allParts.every(v => typeof v === 'string') ) { break; }
}
// Abort processing `include` directives if at least one included sublist
// can't be fetched.
do {
allParts = await Promise.all(allParts);
const part = allParts.find(part => {
return typeof part === 'object' && part.error !== undefined;
});
if ( part !== undefined ) {
return { url: mainlistURL, content: '', error: part.error };
}
allParts = processIncludeDirectives(allParts);
} while ( allParts.some(part => typeof part !== 'string') );
// If we reach this point, this means all fetches were successful.
return {
url: mainlistURL,
content: allParts.length === 1