Skip to content

Commit 06b9b0a

Browse files
committed
catch bad URLs
1 parent 22818a2 commit 06b9b0a

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

Plugins/Flow.Launcher.Plugin.BrowserBookmark/Services/FaviconService.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public partial class FaviconService : IDisposable
2626
private readonly string _faviconCacheDir;
2727
private readonly HttpClient _httpClient;
2828
private readonly LocalFaviconExtractor _localExtractor;
29-
3029
private readonly CancellationTokenSource _cts = new();
3130
private readonly ConcurrentDictionary<string, Task<string?>> _ongoingFetches = new(StringComparer.OrdinalIgnoreCase);
3231

@@ -53,7 +52,7 @@ public FaviconService(PluginInitContext context, Settings settings, string tempP
5352

5453
_faviconCacheDir = Path.Combine(context.CurrentPluginMetadata.PluginCacheDirectoryPath, "FaviconCache");
5554
Directory.CreateDirectory(_faviconCacheDir);
56-
55+
5756
_localExtractor = new LocalFaviconExtractor(context, tempPath);
5857

5958
var handler = new HttpClientHandler
@@ -269,6 +268,11 @@ private async Task<FetchResult> FetchAndProcessUrlAsync(Uri faviconUri, Cancella
269268
return new FetchResult(tempPath, size);
270269
}
271270
}
271+
catch (HttpRequestException ex) when (ex.InnerException is System.Net.Sockets.SocketException { SocketErrorCode: System.Net.Sockets.SocketError.HostNotFound })
272+
{
273+
// Host not found is a common, expected error for misconfigured favicons. Don't log as a full error.
274+
_context.API.LogDebug(nameof(FaviconService), $"Favicon host not found for URI: {faviconUri}");
275+
}
272276
catch (TaskCanceledException) when (!token.IsCancellationRequested)
273277
{
274278
_context.API.LogWarn(nameof(FaviconService), $"HttpClient timed out for {faviconUri}.");
@@ -334,7 +338,7 @@ private async Task<List<FaviconCandidate>> GetCandidatesFromHtmlAsync(Uri pageUr
334338
return new List<FaviconCandidate>();
335339
}
336340

337-
private static List<FaviconCandidate> ParseLinkTags(string htmlContent, Uri originalBaseUri)
341+
private List<FaviconCandidate> ParseLinkTags(string htmlContent, Uri originalBaseUri)
338342
{
339343
var candidates = new List<FaviconCandidate>();
340344
var effectiveBaseUri = originalBaseUri;
@@ -361,12 +365,18 @@ private static List<FaviconCandidate> ParseLinkTags(string htmlContent, Uri orig
361365
var href = hrefMatch.Groups["v"].Value;
362366
if (string.IsNullOrWhiteSpace(href)) continue;
363367

368+
_context.API.LogDebug(nameof(ParseLinkTags), $"Found potential favicon link. Raw tag: '{linkTag}', Extracted href: '{href}', Base URI: '{effectiveBaseUri}'");
369+
364370
if (href.StartsWith("//"))
365371
{
366372
href = effectiveBaseUri.Scheme + ":" + href;
367373
}
368374

369-
if (!Uri.TryCreate(effectiveBaseUri, href, out var fullUrl)) continue;
375+
if (!Uri.TryCreate(effectiveBaseUri, href, out var fullUrl))
376+
{
377+
_context.API.LogWarn(nameof(ParseLinkTags), $"Failed to create a valid URI from href: '{href}' and base URI: '{effectiveBaseUri}'");
378+
continue;
379+
}
370380

371381
candidates.Add(new FaviconCandidate(fullUrl.ToString(), CalculateFaviconScore(linkTag, fullUrl.ToString())));
372382
}
@@ -405,6 +415,9 @@ private static int CalculateFaviconScore(string linkTag, string fullUrl)
405415
await stream.CopyToAsync(ms, token);
406416
ms.Position = 0;
407417

418+
// The returned 'Size' is the original width of the icon, used for scoring the best favicon.
419+
// It does not reflect the final dimensions of the resized PNG.
420+
408421
// 1. Try to decode as SVG.
409422
var (pngData, size) = TryConvertSvgToPng(ms);
410423
if (pngData is not null) return (pngData, size);
@@ -413,7 +426,7 @@ private static int CalculateFaviconScore(string linkTag, string fullUrl)
413426
// 2. Try to decode as an ICO file to correctly handle multiple frames.
414427
(pngData, size) = TryConvertIcoToPng(ms);
415428
if (pngData is not null) return (pngData, size);
416-
429+
417430
ms.Position = 0;
418431
// 3. Fallback for simple bitmaps or ICOs that IconBitmapDecoder failed on.
419432
(pngData, size) = TryConvertBitmapToPng(ms);
@@ -477,7 +490,7 @@ private static (byte[]? PngData, int Size) TryConvertIcoToPng(Stream stream)
477490

478491
return (null, 0);
479492
}
480-
493+
481494
private (byte[]? PngData, int Size) TryConvertBitmapToPng(Stream stream)
482495
{
483496
try

0 commit comments

Comments
 (0)