Skip to content

Commit 00edb42

Browse files
authored
Merge pull request #24 from AvaloniaUtils/addLogging
Add errors logging to loaders
2 parents f02aaab + 274706f commit 00edb42

File tree

4 files changed

+50
-12
lines changed

4 files changed

+50
-12
lines changed

AsyncImageLoader.Avalonia/AdvancedImage.axaml.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Threading.Tasks;
44
using Avalonia;
55
using Avalonia.Controls;
6+
using Avalonia.Logging;
67
using Avalonia.Markup.Xaml;
78
using Avalonia.Media;
89
using Avalonia.Media.Imaging;
@@ -74,6 +75,7 @@ public class AdvancedImage : ContentControl
7475
private bool _shouldLoaderChangeTriggerUpdate;
7576

7677
private CancellationTokenSource? _updateCancellationToken;
78+
private readonly ParametrizedLogger? _logger;
7779

7880
static AdvancedImage()
7981
{
@@ -89,6 +91,7 @@ static AdvancedImage()
8991
public AdvancedImage(Uri? baseUri)
9092
{
9193
_baseUri = baseUri;
94+
_logger = Logger.TryGet(LogEventLevel.Error, ImageLoader.AsyncImageLoaderLogArea);
9295
}
9396

9497
/// <summary>
@@ -241,6 +244,12 @@ private async void UpdateImage(string? source, IAsyncImageLoader? loader)
241244
{
242245
return null;
243246
}
247+
catch (Exception e)
248+
{
249+
_logger?.Log(this, "AdvancedImage image resolution failed: {0}", e);
250+
251+
return null;
252+
}
244253
finally
245254
{
246255
cancellationTokenSource.Dispose();

AsyncImageLoader.Avalonia/ImageBrushLoader.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
using AsyncImageLoader.Loaders;
1+
using System;
2+
using AsyncImageLoader.Loaders;
23
using Avalonia;
4+
using Avalonia.Logging;
35
using Avalonia.Media;
6+
using Avalonia.Media.Imaging;
47

58
namespace AsyncImageLoader {
69
public static class ImageBrushLoader {
10+
private static readonly ParametrizedLogger? Logger;
711
public static IAsyncImageLoader AsyncImageLoader { get; set; } = new RamCachedWebImageLoader();
812
static ImageBrushLoader() {
913
SourceProperty.Changed.AddClassHandler<ImageBrush>(OnSourceChanged);
14+
Logger = Avalonia.Logging.Logger.TryGet(LogEventLevel.Error, ImageLoader.AsyncImageLoaderLogArea);
1015
}
1116

1217
private static async void OnSourceChanged(ImageBrush imageBrush, AvaloniaPropertyChangedEventArgs args) {
@@ -16,9 +21,19 @@ private static async void OnSourceChanged(ImageBrush imageBrush, AvaloniaPropert
1621

1722
SetIsLoading(imageBrush, true);
1823

19-
var bitmap = newValue == null
20-
? null
21-
: await AsyncImageLoader.ProvideImageAsync(newValue);
24+
Bitmap? bitmap = null;
25+
try
26+
{
27+
if (newValue is not null)
28+
{
29+
bitmap = await AsyncImageLoader.ProvideImageAsync(newValue);
30+
}
31+
}
32+
catch (Exception e)
33+
{
34+
Logger?.Log("ImageBrushLoader", "ImageBrushLoader image resolution failed: {0}", e);
35+
}
36+
2237
if (GetSource(imageBrush) != newValue) return;
2338
imageBrush.Source = bitmap;
2439

AsyncImageLoader.Avalonia/ImageLoader.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
using Avalonia.Controls;
88
using Avalonia.Media.Imaging;
99
using System.Collections.Concurrent;
10+
using Avalonia.Logging;
1011

1112
namespace AsyncImageLoader;
1213

1314
public static class ImageLoader
1415
{
15-
public const string AsyncImageLoaderLogArea = "AsyncImageLoader";
16+
private static readonly ParametrizedLogger? Logger;
17+
public const string AsyncImageLoaderLogArea = "AsyncImageLoader";
1618

1719
public static readonly AttachedProperty<string?> SourceProperty =
1820
AvaloniaProperty.RegisterAttached<Image, string?>("Source", typeof(ImageLoader));
@@ -23,16 +25,17 @@ public static class ImageLoader
2325
static ImageLoader()
2426
{
2527
SourceProperty.Changed.AddClassHandler<Image>(OnSourceChanged);
28+
Logger = Avalonia.Logging.Logger.TryGet(LogEventLevel.Error, AsyncImageLoaderLogArea);
2629
}
2730

2831
public static IAsyncImageLoader AsyncImageLoader { get; set; } = new RamCachedWebImageLoader();
2932

30-
private static ConcurrentDictionary<Image, CancellationTokenSource> _pendingOperations = new ConcurrentDictionary<Image, CancellationTokenSource>();
33+
private static readonly ConcurrentDictionary<Image, CancellationTokenSource> PendingOperations = new();
3134
private static async void OnSourceChanged(Image sender, AvaloniaPropertyChangedEventArgs args) {
3235
var url = args.GetNewValue<string?>();
3336

3437
// Cancel/Add new pending operation
35-
CancellationTokenSource? cts = _pendingOperations.AddOrUpdate(sender, new CancellationTokenSource(),
38+
CancellationTokenSource? cts = PendingOperations.AddOrUpdate(sender, new CancellationTokenSource(),
3639
(x, y) =>
3740
{
3841
y.Cancel();
@@ -41,7 +44,7 @@ private static async void OnSourceChanged(Image sender, AvaloniaPropertyChangedE
4144

4245
if (url == null)
4346
{
44-
((ICollection<KeyValuePair<Image, CancellationTokenSource>>)_pendingOperations).Remove(new KeyValuePair<Image, CancellationTokenSource>(sender, cts));
47+
((ICollection<KeyValuePair<Image, CancellationTokenSource>>)PendingOperations).Remove(new KeyValuePair<Image, CancellationTokenSource>(sender, cts));
4548
sender.Source = null;
4649
return;
4750
}
@@ -62,13 +65,19 @@ private static async void OnSourceChanged(Image sender, AvaloniaPropertyChangedE
6265
{
6366
return null;
6467
}
68+
catch (Exception e)
69+
{
70+
Logger?.Log(LogEventLevel.Error, "ImageLoader image resolution failed: {0}", e);
71+
72+
return null;
73+
}
6574
});
6675

6776
if (bitmap != null && !cts.Token.IsCancellationRequested)
6877
sender.Source = bitmap!;
6978

7079
// "It is not guaranteed to be thread safe by ICollection, but ConcurrentDictionary's implementation is. Additionally, we recently exposed this API for .NET 5 as a public ConcurrentDictionary.TryRemove"
71-
((ICollection<KeyValuePair<Image, CancellationTokenSource>>)_pendingOperations).Remove(new KeyValuePair<Image, CancellationTokenSource>(sender, cts));
80+
((ICollection<KeyValuePair<Image, CancellationTokenSource>>)PendingOperations).Remove(new KeyValuePair<Image, CancellationTokenSource>(sender, cts));
7281
SetIsLoading(sender, false);
7382
}
7483

AsyncImageLoader.Avalonia/Loaders/BaseWebImageLoader.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public BaseWebImageLoader() : this(new HttpClient(), true) { }
3333
public BaseWebImageLoader(HttpClient httpClient, bool disposeHttpClient) {
3434
HttpClient = httpClient;
3535
_shouldDisposeHttpClient = disposeHttpClient;
36-
_logger = Logger.TryGet(LogEventLevel.Information, ImageLoader.AsyncImageLoaderLogArea);
36+
_logger = Logger.TryGet(LogEventLevel.Error, ImageLoader.AsyncImageLoaderLogArea);
3737
}
3838

3939
protected HttpClient HttpClient { get; }
@@ -69,7 +69,10 @@ await LoadFromLocalAsync(url).ConfigureAwait(false)
6969
await SaveToGlobalCache(url, externalBytes).ConfigureAwait(false);
7070
return bitmap;
7171
}
72-
catch (Exception) {
72+
catch (Exception e)
73+
{
74+
_logger?.Log(this, "Failed to resolve image: {RequestUri}\nException: {Exception}", url, e);
75+
7376
return null;
7477
}
7578
}
@@ -121,7 +124,9 @@ await LoadFromLocalAsync(url).ConfigureAwait(false)
121124
try {
122125
return await HttpClient.GetByteArrayAsync(url).ConfigureAwait(false);
123126
}
124-
catch (Exception) {
127+
catch (Exception e) {
128+
_logger?.Log(this,
129+
"Failed to resolve image from request with uri: {RequestUri}\nException: {Exception}", url, e);
125130
return null;
126131
}
127132
}

0 commit comments

Comments
 (0)