Freika/dawarich · warning
[EventHandlers] Failed to highlight track:
Error message
[EventHandlers] Failed to highlight track:
What it means
Dawarich's MapLibre maps v2 event handler wraps the visual highlight of a clicked track in a defensive try/catch. After a track click it resolves the full feature, stores it as the selected track, and asks LayerManager for the 'tracks' layer to call setSelectedTrack(). Any exception inside that highlight step (layer not registered, map style not ready, layer removed mid-click) is caught and logged with this message; the click flow still continues to load segments and open the timeline.
Source
Thrown at app/javascript/controllers/maps/maplibre/event_handlers.js:678
if (trackPointFeatures.length > 0) return
}
const clickedFeature = e.features[0]
if (!clickedFeature) return
const properties = clickedFeature.properties
const fullFeature = this._getFullTrackFeature(properties) || clickedFeature
this.selectedTrackFeature = fullFeature
// Keep the on-map highlight + segment visualization — those are visual
// feedback for the click itself, independent of the info surface.
try {
const tracksLayer = this.controller.layerManager.getLayer("tracks")
if (tracksLayer?.setSelectedTrack) {
tracksLayer.setSelectedTrack(fullFeature)
}
} catch (err) {
console.warn("[EventHandlers] Failed to highlight track:", err)
}
this._loadTrackSegments(properties.id, fullFeature)
// Derive the day from the track's start. `start_at` comes from our own
// serializer as an ISO8601 string — safe to slice the date portion.
const startAt =
typeof properties.start_at === "string" ? properties.start_at : null
const date = startAt ? startAt.slice(0, 10) : null
const trackId = Number(properties.id)
document.dispatchEvent(
new CustomEvent("timeline:open-track", {
detail: { trackId, date, startAt },
}),
)
}
/**View on GitHub (pinned to 97fad417c5)
Solutions
- Inspect the error object logged after the message — it names the exact layer or paint property that failed
- Gate the highlight on readiness: check layerManager.getLayer('tracks') exists and map.isStyleLoaded() before calling setSelectedTrack
- Make TracksLayer.setSelectedTrack defensive: early-return unless this.map.getLayer(this.layerId) exists
- If it fires after Turbo navigation, clear handlers in the Stimulus controller's disconnect() so post-teardown clicks cannot reach a dead map
Example fix
// before
const tracksLayer = this.controller.layerManager.getLayer("tracks")
if (tracksLayer?.setSelectedTrack) {
tracksLayer.setSelectedTrack(fullFeature)
}
// after
const tracksLayer = this.controller.layerManager.getLayer("tracks")
const mapReady = this.controller.map?.isStyleLoaded?.() === true
if (tracksLayer?.setSelectedTrack && mapReady) {
tracksLayer.setSelectedTrack(fullFeature)
} else {
console.debug("[EventHandlers] Tracks layer not ready, skipping highlight")
} Defensive patterns
Strategy: try-catch
Validate before calling
const layer = this.controller.layerManager.getLayer("tracks")
const ready =
Boolean(layer && typeof layer.setSelectedTrack === "function") &&
this.controller.map?.isStyleLoaded?.() === true
if (!ready) return // skip the highlight instead of risking a throw Type guard
/** @param {object} controller @returns {boolean} */
function canHighlightTrack(controller) {
const layer = controller.layerManager?.getLayer("tracks")
return Boolean(
layer &&
typeof layer.setSelectedTrack === "function" &&
controller.map &&
typeof controller.map.getLayer === "function" &&
controller.map.styleLoaded()
)
} Try / catch
try {
tracksLayer.setSelectedTrack(fullFeature)
} catch (err) {
// Visual-only feedback: log and keep the click flow going (segments + timeline)
console.warn("[EventHandlers] Failed to highlight track:", err)
} Prevention
- Register the tracks layer before binding click handlers that depend on it
- Clear selected-track state and unbind click handlers in the controller's disconnect() lifecycle method
- Treat highlight failures as non-fatal: never let them abort segment loading or the timeline dispatch
When it happens
Trigger: Clicking a track before LayerManager.addLayers() has registered the 'tracks' layer (style/tiles still loading); clicking while a style swap or layer toggle removes the layer underneath setSelectedTrack(); a refactor renaming the layer id so getLayer('tracks') returns an unexpected object; map torn down by Turbo navigation while the click handler chain is still running.
Common situations: Users clicking tracks immediately after page load on slow connections; Turbo cache restoring a stale page whose listeners outlive the map; layer ids changed during Maps v2 refactoring; highlight invoked after removeLayer during filter changes.
Related errors
- Failed to add photos layer:
- [TracksLayer] Animation frame error:
- Failed to fetch points: ${response.statusText}
- Invalid tile coordinates
- Could not classify zip contents -- file may be corrupted
AI-assisted analysis of Freika/dawarich@97fad417c5 (2026-08-21).
Data as JSON: /api/errors/629c450b8891c4d9.
Report an issue: GitHub.