mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
Map v2 will no longer block the UI when Immich/Photoprism integration has a bad URL or is unreachable (#2113)
This commit is contained in:
parent
8ecb2e3765
commit
24cbabf3b7
6 changed files with 43 additions and 17 deletions
|
|
@ -8,8 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
## Fixed
|
||||
|
||||
- Months are now correctly ordered (Jan-Dec) in the year-end digest chart instead of being sorted alphabetically.
|
||||
- Time spent in a country and city is now calculated correctly for the year-end digest email. #2104
|
||||
|
||||
- Updated Trix to fix a XSS vulnerability. #2102
|
||||
- Map v2 UI no longer blocks when Immich/Photoprism integration has a bad URL or is unreachable. Added 10-second timeout to photo API requests and improved error handling to prevent UI freezing during initial load. #2085
|
||||
|
||||
# [0.37.1] - 2025-12-30
|
||||
|
||||
|
|
|
|||
|
|
@ -56,22 +56,36 @@ export class DataLoader {
|
|||
}
|
||||
data.visitsGeoJSON = this.visitsToGeoJSON(data.visits)
|
||||
|
||||
// Fetch photos
|
||||
// Fetch photos - only if photos layer is enabled and integration is configured
|
||||
// Skip API call if photos are disabled to avoid blocking on failed integrations
|
||||
if (this.settings.photosEnabled) {
|
||||
try {
|
||||
console.log('[Photos] Fetching photos from:', startDate, 'to', endDate)
|
||||
data.photos = await this.api.fetchPhotos({
|
||||
// Use Promise.race to enforce a client-side timeout
|
||||
const photosPromise = this.api.fetchPhotos({
|
||||
start_at: startDate,
|
||||
end_at: endDate
|
||||
})
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Photo fetch timeout')), 15000) // 15 second timeout
|
||||
)
|
||||
|
||||
data.photos = await Promise.race([photosPromise, timeoutPromise])
|
||||
console.log('[Photos] Fetched photos:', data.photos.length, 'photos')
|
||||
console.log('[Photos] Sample photo:', data.photos[0])
|
||||
} catch (error) {
|
||||
console.error('[Photos] Failed to fetch photos:', error)
|
||||
console.warn('[Photos] Failed to fetch photos (non-blocking):', error.message)
|
||||
data.photos = []
|
||||
}
|
||||
} else {
|
||||
console.log('[Photos] Photos layer disabled, skipping fetch')
|
||||
data.photos = []
|
||||
}
|
||||
data.photosGeoJSON = this.photosToGeoJSON(data.photos)
|
||||
console.log('[Photos] Converted to GeoJSON:', data.photosGeoJSON.features.length, 'features')
|
||||
if (data.photosGeoJSON.features.length > 0) {
|
||||
console.log('[Photos] Sample feature:', data.photosGeoJSON.features[0])
|
||||
}
|
||||
|
||||
// Fetch areas
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,10 @@ class Immich::RequestPhotos
|
|||
while page <= max_pages
|
||||
response = JSON.parse(
|
||||
HTTParty.post(
|
||||
immich_api_base_url, headers: headers, body: request_body(page)
|
||||
immich_api_base_url,
|
||||
headers: headers,
|
||||
body: request_body(page),
|
||||
timeout: 10
|
||||
).body
|
||||
)
|
||||
Rails.logger.debug('==== IMMICH RESPONSE ====')
|
||||
|
|
@ -46,6 +49,9 @@ class Immich::RequestPhotos
|
|||
end
|
||||
|
||||
data.flatten
|
||||
rescue HTTParty::Error, Net::OpenTimeout, Net::ReadTimeout => e
|
||||
Rails.logger.error("Immich photo fetch failed: #{e.message}")
|
||||
[]
|
||||
end
|
||||
|
||||
def headers
|
||||
|
|
|
|||
|
|
@ -43,13 +43,17 @@ class Photoprism::RequestPhotos
|
|||
end
|
||||
|
||||
data.flatten
|
||||
rescue HTTParty::Error, Net::OpenTimeout, Net::ReadTimeout => e
|
||||
Rails.logger.error("Photoprism photo fetch failed: #{e.message}")
|
||||
[]
|
||||
end
|
||||
|
||||
def fetch_page(offset)
|
||||
response = HTTParty.get(
|
||||
photoprism_api_base_url,
|
||||
headers: headers,
|
||||
query: request_params(offset)
|
||||
query: request_params(offset),
|
||||
timeout: 10
|
||||
)
|
||||
|
||||
if response.code != 200
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@
|
|||
</h2>
|
||||
<div class="w-full h-48 bg-base-200 rounded-lg p-4 relative">
|
||||
<%= column_chart(
|
||||
@digest.monthly_distances.sort.map { |month, distance_meters|
|
||||
@digest.monthly_distances.sort_by { |month, _| month.to_i }.map { |month, distance_meters|
|
||||
[Date::ABBR_MONTHNAMES[month.to_i], Users::Digest.convert_distance(distance_meters.to_i, @distance_unit).round]
|
||||
},
|
||||
height: '200px',
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
</h2>
|
||||
<div class="w-full h-64 bg-base-100 rounded-lg p-4">
|
||||
<%= column_chart(
|
||||
@digest.monthly_distances.sort.map { |month, distance_meters|
|
||||
@digest.monthly_distances.sort_by { |month, _| month.to_i }.map { |month, distance_meters|
|
||||
[Date::ABBR_MONTHNAMES[month.to_i], Users::Digest.convert_distance(distance_meters.to_i, @distance_unit).round]
|
||||
},
|
||||
height: '250px',
|
||||
|
|
|
|||
Loading…
Reference in a new issue