commit f07178234252bb5e961a6306b6419bd2bcb0e0ae
parent d925b61c660e64e8445d519c5ea3fa4ea6e4f044
Author: Silas Brack <silasbrack@gmail.com>
Date: Sun, 7 Jun 2026 21:55:05 +0200
fix: revert realtime polling, add error logging for API failures
- Remove HTMX polling on comments section (trailbase doesn't
support table-level subscriptions)
- Add tracing::error! to all silent API failures (votes, tags,
profile lookups) so errors show in logs instead of being swallowed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
6 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/handlers/comment.rs b/src/handlers/comment.rs
@@ -75,6 +75,7 @@ pub async fn get_comments(
let voted_comment_ids = if tokens.is_some() && !comment_ids.is_empty() {
trailbase::get_user_votes(&client, trailbase::TARGET_TYPE_COMMENT, &comment_ids)
.await
+ .inspect_err(|e| tracing::error!("Failed to get comment votes: {}", e))
.unwrap_or_default()
} else {
vec![]
@@ -84,6 +85,7 @@ pub async fn get_comments(
for comment in comments {
let author = trailbase::get_user_profile_by_id(&client, &comment.created_by)
.await
+ .inspect_err(|e| tracing::error!("Failed to get profile for {}: {}", comment.created_by, e))
.ok()
.flatten()
.map(|p| p.username);
diff --git a/src/handlers/feed.rs b/src/handlers/feed.rs
@@ -81,6 +81,7 @@ async fn fetch_feed(
let voted_ids = if tokens.is_some() {
trailbase::get_user_votes(&client, TARGET_TYPE_STORY, &story_ids)
.await
+ .inspect_err(|e| tracing::error!("Failed to get user votes: {}", e))
.unwrap_or_default()
} else {
vec![]
@@ -93,12 +94,13 @@ async fn fetch_feed(
for (idx, story) in stories.into_iter().enumerate() {
let tags = trailbase::get_categories_for_story(&client, story.id)
.await
+ .inspect_err(|e| tracing::error!("Failed to get tags for story {}: {}", story.id, e))
.unwrap_or_default();
- // Get author username if available
let author_username = if let Some(ref created_by) = story.created_by {
trailbase::get_user_profile_by_id(&client, created_by)
.await
+ .inspect_err(|e| tracing::error!("Failed to get profile for {}: {}", created_by, e))
.ok()
.flatten()
.map(|p| p.username)
diff --git a/src/handlers/story.rs b/src/handlers/story.rs
@@ -36,12 +36,13 @@ pub async fn show_story(
// Get tags for the story
let tags = trailbase::get_categories_for_story(&client, id)
.await
+ .inspect_err(|e| tracing::error!("Failed to get tags for story {}: {}", id, e))
.unwrap_or_default();
- // Get author username
let author_username = if let Some(ref created_by) = story.created_by {
trailbase::get_user_profile_by_id(&client, created_by)
.await
+ .inspect_err(|e| tracing::error!("Failed to get profile for {}: {}", created_by, e))
.ok()
.flatten()
.map(|p| p.username)
@@ -49,21 +50,21 @@ pub async fn show_story(
None
};
- // Check if user voted on the story
let story_voted = if tokens.is_some() {
trailbase::get_user_votes(&client, TARGET_TYPE_STORY, &[id])
.await
+ .inspect_err(|e| tracing::error!("Failed to get votes: {}", e))
.map(|v| v.contains(&id))
.unwrap_or(false)
} else {
false
};
- // Check which comments the user voted on
let comment_ids: Vec<i64> = comments.iter().map(|c| c.id).collect();
let voted_comment_ids = if tokens.is_some() && !comment_ids.is_empty() {
trailbase::get_user_votes(&client, TARGET_TYPE_COMMENT, &comment_ids)
.await
+ .inspect_err(|e| tracing::error!("Failed to get comment votes: {}", e))
.unwrap_or_default()
} else {
vec![]
@@ -78,6 +79,7 @@ pub async fn show_story(
for comment in comments {
let comment_author = trailbase::get_user_profile_by_id(&client, &comment.created_by)
.await
+ .inspect_err(|e| tracing::error!("Failed to get profile for {}: {}", comment.created_by, e))
.ok()
.flatten()
.map(|p| p.username);
diff --git a/src/handlers/tag.rs b/src/handlers/tag.rs
@@ -53,23 +53,25 @@ pub async fn show_tag(
let voted_ids = if tokens.is_some() && !story_ids.is_empty() {
trailbase::get_user_votes(&client, TARGET_TYPE_STORY, &story_ids)
.await
+ .inspect_err(|e| tracing::error!("Failed to get votes: {}", e))
.unwrap_or_default()
} else {
vec![]
};
- // Enrich stories
let mut enriched_stories = Vec::with_capacity(stories.len());
let base_rank = query.page * PAGE_LIMIT;
for (idx, story) in stories.into_iter().enumerate() {
let tags = trailbase::get_categories_for_story(&client, story.id)
.await
+ .inspect_err(|e| tracing::error!("Failed to get tags for story {}: {}", story.id, e))
.unwrap_or_default();
let author_username = if let Some(ref created_by) = story.created_by {
trailbase::get_user_profile_by_id(&client, created_by)
.await
+ .inspect_err(|e| tracing::error!("Failed to get profile for {}: {}", created_by, e))
.ok()
.flatten()
.map(|p| p.username)
diff --git a/src/handlers/user.rs b/src/handlers/user.rs
@@ -53,6 +53,7 @@ pub async fn show_user(
let voted_ids = if tokens.is_some() && !story_ids.is_empty() {
trailbase::get_user_votes(&client, TARGET_TYPE_STORY, &story_ids)
.await
+ .inspect_err(|e| tracing::error!("Failed to get votes: {}", e))
.unwrap_or_default()
} else {
vec![]
@@ -61,6 +62,7 @@ pub async fn show_user(
for (idx, story) in stories.into_iter().enumerate() {
let tags = trailbase::get_categories_for_story(&client, story.id)
.await
+ .inspect_err(|e| tracing::error!("Failed to get tags for story {}: {}", story.id, e))
.unwrap_or_default();
let time_ago = trailbase::time_ago(&story.published);
let user_voted = voted_ids.contains(&story.id);
diff --git a/templates/story.html b/templates/story.html
@@ -82,11 +82,7 @@
<p class="login-prompt"><a href="/login">Log in</a> to comment.</p>
{% endif %}
- <section class="comments"
- hx-get="/story/{{ story.id }}/comments"
- hx-trigger="every 10s"
- hx-swap="innerHTML"
- >
+ <section class="comments">
{% include "comments.html" %}
</section>
</div>