FossilRepo

Fix ticket_detail 500: handle empty username in comment user link

ragelink 2026-04-08 14:03 trunk
Commit 2a7d4d4ac0f39a7d2b8e97a10996d1ee0fc428fa105513adadfb629420bad2a2
+1 -27
--- fossil/views.py
+++ fossil/views.py
@@ -768,51 +768,25 @@
768768
},
769769
)
770770
771771
772772
def ticket_detail(request, slug, ticket_uuid):
773
- import logging
774
- import traceback as tb_mod
775
-
776
- logger = logging.getLogger("fossil.views")
777
-
778
- try:
779
- return _ticket_detail_inner(request, slug, ticket_uuid)
780
- except Exception:
781
- logger.exception("ticket_detail 500 for %s/%s", slug, ticket_uuid)
782
- with open("/tmp/fossilrepo_ticket_detail_error.log", "a") as f:
783
- f.write(f"\n--- {ticket_uuid} ---\n")
784
- tb_mod.print_exc(file=f)
785
- raise
786
-
787
-
788
-def _ticket_detail_inner(request, slug, ticket_uuid):
789
- import logging
790
-
791
- logger = logging.getLogger("fossil.views")
792
-
793773
project, fossil_repo, reader = _get_repo_and_reader(slug, request)
794774
795775
with reader:
796776
ticket = reader.get_ticket_detail(ticket_uuid)
797777
comments = reader.get_ticket_comments(ticket_uuid) if ticket else []
798778
799779
if not ticket:
800780
raise Http404("Ticket not found")
801781
802
- try:
803
- body_html = mark_safe(sanitize_html(_render_fossil_content(ticket.body, project_slug=slug))) if ticket.body else ""
804
- except Exception:
805
- logger.exception("ticket_detail: failed to render body for %s", ticket_uuid)
806
- body_html = mark_safe(f"<pre>{ticket.body}</pre>") if ticket.body else ""
807
-
782
+ body_html = mark_safe(sanitize_html(_render_fossil_content(ticket.body, project_slug=slug))) if ticket.body else ""
808783
rendered_comments = []
809784
for c in comments:
810785
try:
811786
comment_html = mark_safe(sanitize_html(_render_fossil_content(c["comment"], project_slug=slug)))
812787
except Exception:
813
- logger.exception("ticket_detail: failed to render comment for %s", ticket_uuid)
814788
comment_html = mark_safe(f"<pre>{c['comment']}</pre>")
815789
rendered_comments.append(
816790
{
817791
"user": c["user"],
818792
"timestamp": c["timestamp"],
819793
--- fossil/views.py
+++ fossil/views.py
@@ -768,51 +768,25 @@
768 },
769 )
770
771
772 def ticket_detail(request, slug, ticket_uuid):
773 import logging
774 import traceback as tb_mod
775
776 logger = logging.getLogger("fossil.views")
777
778 try:
779 return _ticket_detail_inner(request, slug, ticket_uuid)
780 except Exception:
781 logger.exception("ticket_detail 500 for %s/%s", slug, ticket_uuid)
782 with open("/tmp/fossilrepo_ticket_detail_error.log", "a") as f:
783 f.write(f"\n--- {ticket_uuid} ---\n")
784 tb_mod.print_exc(file=f)
785 raise
786
787
788 def _ticket_detail_inner(request, slug, ticket_uuid):
789 import logging
790
791 logger = logging.getLogger("fossil.views")
792
793 project, fossil_repo, reader = _get_repo_and_reader(slug, request)
794
795 with reader:
796 ticket = reader.get_ticket_detail(ticket_uuid)
797 comments = reader.get_ticket_comments(ticket_uuid) if ticket else []
798
799 if not ticket:
800 raise Http404("Ticket not found")
801
802 try:
803 body_html = mark_safe(sanitize_html(_render_fossil_content(ticket.body, project_slug=slug))) if ticket.body else ""
804 except Exception:
805 logger.exception("ticket_detail: failed to render body for %s", ticket_uuid)
806 body_html = mark_safe(f"<pre>{ticket.body}</pre>") if ticket.body else ""
807
808 rendered_comments = []
809 for c in comments:
810 try:
811 comment_html = mark_safe(sanitize_html(_render_fossil_content(c["comment"], project_slug=slug)))
812 except Exception:
813 logger.exception("ticket_detail: failed to render comment for %s", ticket_uuid)
814 comment_html = mark_safe(f"<pre>{c['comment']}</pre>")
815 rendered_comments.append(
816 {
817 "user": c["user"],
818 "timestamp": c["timestamp"],
819
--- fossil/views.py
+++ fossil/views.py
@@ -768,51 +768,25 @@
768 },
769 )
770
771
772 def ticket_detail(request, slug, ticket_uuid):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
773 project, fossil_repo, reader = _get_repo_and_reader(slug, request)
774
775 with reader:
776 ticket = reader.get_ticket_detail(ticket_uuid)
777 comments = reader.get_ticket_comments(ticket_uuid) if ticket else []
778
779 if not ticket:
780 raise Http404("Ticket not found")
781
782 body_html = mark_safe(sanitize_html(_render_fossil_content(ticket.body, project_slug=slug))) if ticket.body else ""
 
 
 
 
 
783 rendered_comments = []
784 for c in comments:
785 try:
786 comment_html = mark_safe(sanitize_html(_render_fossil_content(c["comment"], project_slug=slug)))
787 except Exception:
 
788 comment_html = mark_safe(f"<pre>{c['comment']}</pre>")
789 rendered_comments.append(
790 {
791 "user": c["user"],
792 "timestamp": c["timestamp"],
793
--- templates/fossil/ticket_detail.html
+++ templates/fossil/ticket_detail.html
@@ -80,11 +80,11 @@
8080
<h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3">Comments ({{ comments|length }})</h3>
8181
<div class="space-y-3">
8282
{% for c in comments %}
8383
<div class="rounded-lg bg-gray-800 border border-gray-700">
8484
<div class="px-5 py-3 border-b border-gray-700 flex items-center justify-between">
85
- <a href="{% url 'fossil:user_activity' slug=project.slug username=c.user %}" class="text-sm font-medium text-gray-200 hover:text-brand-light">{{ c.user|display_user }}</a>
85
+ {% if c.user %}<a href="{% url 'fossil:user_activity' slug=project.slug username=c.user %}" class="text-sm font-medium text-gray-200 hover:text-brand-light">{{ c.user|display_user }}</a>{% else %}<span class="text-sm font-medium text-gray-400">system</span>{% endif %}
8686
<span class="text-xs text-gray-500">{{ c.timestamp|timesince }} ago</span>
8787
</div>
8888
<div class="px-5 py-4">
8989
<div class="prose prose-invert prose-gray prose-sm max-w-none">
9090
{{ c.html }}
9191
--- templates/fossil/ticket_detail.html
+++ templates/fossil/ticket_detail.html
@@ -80,11 +80,11 @@
80 <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3">Comments ({{ comments|length }})</h3>
81 <div class="space-y-3">
82 {% for c in comments %}
83 <div class="rounded-lg bg-gray-800 border border-gray-700">
84 <div class="px-5 py-3 border-b border-gray-700 flex items-center justify-between">
85 <a href="{% url 'fossil:user_activity' slug=project.slug username=c.user %}" class="text-sm font-medium text-gray-200 hover:text-brand-light">{{ c.user|display_user }}</a>
86 <span class="text-xs text-gray-500">{{ c.timestamp|timesince }} ago</span>
87 </div>
88 <div class="px-5 py-4">
89 <div class="prose prose-invert prose-gray prose-sm max-w-none">
90 {{ c.html }}
91
--- templates/fossil/ticket_detail.html
+++ templates/fossil/ticket_detail.html
@@ -80,11 +80,11 @@
80 <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wider mb-3">Comments ({{ comments|length }})</h3>
81 <div class="space-y-3">
82 {% for c in comments %}
83 <div class="rounded-lg bg-gray-800 border border-gray-700">
84 <div class="px-5 py-3 border-b border-gray-700 flex items-center justify-between">
85 {% if c.user %}<a href="{% url 'fossil:user_activity' slug=project.slug username=c.user %}" class="text-sm font-medium text-gray-200 hover:text-brand-light">{{ c.user|display_user }}</a>{% else %}<span class="text-sm font-medium text-gray-400">system</span>{% endif %}
86 <span class="text-xs text-gray-500">{{ c.timestamp|timesince }} ago</span>
87 </div>
88 <div class="px-5 py-4">
89 <div class="prose prose-invert prose-gray prose-sm max-w-none">
90 {{ c.html }}
91

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button