Skip to content

Commit 7d9dd32

Browse files
authored
fix: ensure tiles still load when failing to generate cache metadata (fleaflet#2125)
1 parent 8964171 commit 7d9dd32

File tree

7 files changed

+58
-7
lines changed

7 files changed

+58
-7
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ Please consider [donating](https://github.com/sponsors/fleaflet) or [contributin
44

55
This CHANGELOG does not include every commit and/or PR - it is a hand picked selection of the ones that have an effect on you. For a full list of changes, please check the GitHub repository releases/tags.
66

7+
## [8.2.1] - 2025/07/11
8+
9+
Contains the following user-affecting changes:
10+
11+
- Ensure tiles still load when failing to cache them due to HTTP spec non-compliance - [#2125](https://github.com/fleaflet/flutter_map/pull/2125) for [#2124](https://github.com/fleaflet/flutter_map/issues/2124)
12+
- Log informational warnings to console when a tile fails to cache due to HTTP spec non-compliance or a shortage of information to calculate an accurate freshness age - [#2125](https://github.com/fleaflet/flutter_map/pull/2125) for [#2124](https://github.com/fleaflet/flutter_map/issues/2124)
13+
14+
Many thanks to these contributors (in no particular order):
15+
16+
- ... and all the maintainers
17+
718
## [8.2.0] - 2025/07/10
819

920
Contains the following user-affecting changes:

example/pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ packages:
116116
path: ".."
117117
relative: true
118118
source: path
119-
version: "8.2.0"
119+
version: "8.2.1"
120120
flutter_test:
121121
dependency: "direct dev"
122122
description: flutter

example/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: flutter_map_example
22
description: Example application for 'flutter_map' package
33
publish_to: "none"
4-
version: 8.2.0
4+
version: 8.2.1
55

66
environment:
77
sdk: ">=3.6.0 <4.0.0"

lib/src/layer/tile_layer/tile_provider/network/caching/tile_metadata.dart

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import 'dart:io' show HttpHeaders, HttpDate; // web safe!
22
import 'dart:math';
33

4+
import 'package:flutter/foundation.dart';
45
import 'package:flutter_map/flutter_map.dart';
5-
import 'package:meta/meta.dart';
6+
import 'package:logger/logger.dart';
67

78
/// Metadata about a tile cached with a [MapCachingProvider]
89
///
@@ -24,11 +25,27 @@ class CachedMapTileMetadata {
2425
/// Create new metadata based off an HTTP response's headers
2526
///
2627
/// Where a response does not include enough information to calculate the
27-
/// freshness age, [fallbackFreshnessAge] is used.
28+
/// freshness age, [fallbackFreshnessAge] is used. This will emit a console
29+
/// log in debug mode if [warnOnFallbackUsage] is is set.
30+
///
31+
/// This may throw if the required headers were in an unexpected format.
2832
factory CachedMapTileMetadata.fromHttpHeaders(
2933
Map<String, String> headers, {
34+
Uri? warnOnFallbackUsage,
3035
Duration fallbackFreshnessAge = const Duration(days: 7),
3136
}) {
37+
void warnFallbackUsage() {
38+
if (kDebugMode && warnOnFallbackUsage != null) {
39+
Logger(printer: SimplePrinter()).w(
40+
'[flutter_map cache] Using fallback freshness age '
41+
'($fallbackFreshnessAge) for ${warnOnFallbackUsage.path}\n'
42+
'\tThis indicates the tile server did not send enough '
43+
'information to calculate a freshness age. Optionally override '
44+
"in the caching provider's config.",
45+
);
46+
}
47+
}
48+
3249
// There is no guarantee that this meets the HTTP specification - however,
3350
// it was designed with it in mind
3451
DateTime calculateStaleAt() {
@@ -44,6 +61,7 @@ class CachedMapTileMetadata {
4461
return HttpDate.parse(expires);
4562
}
4663

64+
warnFallbackUsage();
4765
return addToNow(fallbackFreshnessAge);
4866
}
4967

@@ -62,6 +80,7 @@ class CachedMapTileMetadata {
6280
return addToNow(Duration(seconds: int.parse(maxAge) - estimatedAge));
6381
}
6482

83+
warnFallbackUsage();
6584
return addToNow(fallbackFreshnessAge);
6685
}
6786

lib/src/layer/tile_layer/tile_provider/network/image_provider/image_provider.dart

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:flutter/painting.dart';
77
import 'package:flutter_map/flutter_map.dart';
88
import 'package:flutter_map/src/layer/tile_layer/tile_provider/network/image_provider/consolidate_response.dart';
99
import 'package:http/http.dart';
10+
import 'package:logger/logger.dart';
1011
import 'package:meta/meta.dart';
1112

1213
/// Dedicated [ImageProvider] to fetch tiles from the network
@@ -48,6 +49,9 @@ class NetworkTileImageProvider extends ImageProvider<NetworkTileImageProvider> {
4849
/// Whether to ignore exceptions and errors that occur whilst fetching tiles
4950
/// over the network, and just return a transparent tile
5051
///
52+
/// Also silences any exceptions generated when attempting to write tiles to
53+
/// the cache.
54+
///
5155
/// Not included in [operator==].
5256
final bool silenceExceptions;
5357

@@ -174,9 +178,26 @@ class NetworkTileImageProvider extends ImageProvider<NetworkTileImageProvider> {
174178
required Map<String, String> headers,
175179
}) {
176180
if (useFallback || !cachingProvider.isSupported) return;
181+
182+
late final CachedMapTileMetadata metadata;
183+
try {
184+
metadata = CachedMapTileMetadata.fromHttpHeaders(
185+
headers,
186+
warnOnFallbackUsage: silenceExceptions ? null : uri,
187+
);
188+
} catch (e) {
189+
if (kDebugMode && !silenceExceptions) {
190+
Logger(printer: SimplePrinter()).w(
191+
'[flutter_map cache] Failed to cache ${uri.path}: $e\n\tThis may '
192+
'indicate a HTTP spec non-conformance issue with the tile server. ',
193+
);
194+
}
195+
return;
196+
}
197+
177198
cachingProvider.putTile(
178199
url: resolvedUrl,
179-
metadata: CachedMapTileMetadata.fromHttpHeaders(headers),
200+
metadata: metadata,
180201
bytes: bytes,
181202
);
182203
}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: flutter_map
22
description: "Flutter's №1 non-commercially aimed map client: it's easy-to-use, versatile, vendor-free, fully cross-platform, and 100% pure-Flutter"
3-
version: 8.2.0
3+
version: 8.2.1
44

55
repository: https://github.com/fleaflet/flutter_map
66
issue_tracker: https://github.com/fleaflet/flutter_map/issues

windowsApplicationInstallerSetup.iss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
33

44
#define MyAppName "flutter_map Demo"
5-
#define MyAppVersion "for 8.2.0"
5+
#define MyAppVersion "for 8.2.1"
66
#define MyAppPublisher "fleaflet"
77
#define MyAppURL "https://github.com/fleaflet/flutter_map"
88
#define MyAppSupportURL "https://github.com/fleaflet/flutter_map/issues"

0 commit comments

Comments
 (0)