mirror of
https://github.com/bugsink/bugsink.git
synced 2026-01-08 22:30:28 -06:00
(Whether this is needed in practice is unsure; I implemented this before I noticed that in such cases frame.context_line is also always missing in my data-set; but I havent' checked the spec and leaving it in defensively really won't hurt)
104 lines
6.8 KiB
HTML
104 lines
6.8 KiB
HTML
{% extends "issues/base.html" %}
|
|
{% load static %}
|
|
{% load stricter_templates %}
|
|
{% load issues %}
|
|
|
|
{% block tab_content %}
|
|
{# <div class="font-bold">Stacktrace:</div> I think this is obvious?#}
|
|
{% for exception in exceptions %}
|
|
{# option: make multi-exception stacktraces more clear <div class="border-l-4 border-cyan-500 pl-4"> }#}
|
|
|
|
<div class="flex">
|
|
<div class="overflow-hidden">
|
|
<h1 class="text-2xl font-bold {% if forloop.counter0 > 0 %}mt-4{% endif %} text-ellipsis whitespace-nowrap overflow-hidden">{{ exception.type }}</h1> {# potentially: hide this whole block if there is only a single exception #}
|
|
<div class="text-lg mb-4 text-ellipsis whitespace-nowrap overflow-hidden">{{ exception.value }}</div>
|
|
|
|
</div>
|
|
{% if forloop.counter0 == 0 %}
|
|
<div class="ml-auto flex-none">
|
|
<div class="flex place-content-end">
|
|
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring" onclick="showAllFrames()">Show all</button>
|
|
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring" onclick="showInAppFrames()">Show in-app</button>
|
|
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring" onclick="showRaisingFrame()">Show raise</button>
|
|
<button class="font-bold text-slate-500 border-slate-300 pl-4 pr-4 pb-1 pt-1 mr-2 border-2 rounded-md hover:bg-slate-200 active:ring" onclick="hideAllFrames()">Collapse all</button>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% for frame in exception.stacktrace.frames %}
|
|
{% with frame=frame|pygmentize %}
|
|
|
|
<div class="bg-white w-full font-mono"> {# per frame div #}
|
|
|
|
<div class="flex pl-4 pt-2 pb-2 border-b-2 {% if forloop.first %}border-t-2{% endif %} bg-slate-100 border-slate-400 cursor-pointer" onclick="toggleFrameVisibility(this)"> {# per frame header div #}
|
|
|
|
<div> {# filename, function, lineno #}
|
|
{% if frame.in_app %}
|
|
<span class="font-bold">{{ frame.filename }}</span>{% if frame.function %} in <span class="font-bold">{{ frame.function }}</span>{% endif %} line <span class="font-bold">{{ frame.lineno }}</span>.
|
|
{% else %}
|
|
<span class="italic">{{ frame.filename }}{% if frame.function %} in {{ frame.function }}{% endif %} line {{ frame.lineno }}.</span>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="ml-auto pr-4">{# chevron #}
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5 js-chevron transition-all {% if forloop.parentloop.last and forloop.last %}rotate-180{% endif %}">
|
|
<path fill-rule="evenodd" d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z" clip-rule="evenodd" />
|
|
</svg>
|
|
</div>
|
|
</div> {# per frame header div #}
|
|
|
|
<div class="js-frame-details {% if frame.in_app %}js-in-app{% endif %} border-slate-400 overflow-hidden transition-all {% if forloop.parentloop.last and forloop.last %}js-raising-frame{% endif %}"
|
|
{% if not forloop.parentloop.last or not forloop.last %}data-collapsed="true" style="height: 0px"{% endif %}> {# collapsable part #}
|
|
|
|
<div class="pl-6 pr-6 pt-8 {% if not forloop.last %}border-b-2 border-slate-400{% endif %}">{# convience div for padding & border; the border is basically the top-border of the next header #}
|
|
<div class="bg-slate-50 syntax-coloring">{# code listing #}
|
|
{# the spread-out pX-6 in this code is intentional to ensure the padding is visible when scrolling to the right, and not visible when scrolling is possible (i.e. the text is cut-off awkwardly to hint at scrolling #}
|
|
<ol class="list-decimal overflow-x-auto list-inside pt-6 pb-6 {% if frame|firstlineno is None %}list-none{% endif %}" start="{{ frame|firstlineno }}">
|
|
{% for line in frame.pre_context %}<li class="pl-6"><div class="whitespace-pre w-full inline pr-6">{{ line }} {# leave space to avoid collapse #}</div></li>{% endfor %}
|
|
{# the gradient is a workaround, because I can't get a full-width elem going here inside the overflow #}
|
|
{# when some other line is overflowing. Using the gradient hides this fact (it happens to also look good) #}
|
|
<li class="pl-6 bg-gradient-to-r from-slate-300 font-bold w-full"><div class="whitespace-pre w-full inline pr-6">{{ frame.context_line }} {# leave space to avoid collapse #}</div></li>
|
|
{% for line in frame.post_context %}<li class="pl-6"><div class="whitespace-pre w-full inline pr-6">{{ line }} {# leave space to avoid collapse #}</div></li>{% endfor %}
|
|
</ol>
|
|
</div>
|
|
|
|
{% if frame.vars %}
|
|
<div class="pt-4 pb-6">{# variables #}
|
|
<div class="flex">
|
|
<div class="w-1/4 pt-2 font-bold border-b-2 border-slate-500 pl-4">Variable</div>
|
|
<div class="w-3/4 pt-2 font-bold border-b-2 border-slate-500 pr-4">Value</div>
|
|
</div>
|
|
{% for var, value in frame.vars|items %}
|
|
<div class="flex">
|
|
<div class="w-1/4 pl-4 {% if not forloop.last %}border-b-2 border-dotted border-slate-300{% endif %}">{{ var }}</div>
|
|
<div class="w-3/4 pr-4 {% if not forloop.last %} border-b-2 border-dotted border-slate-300{% endif %}">{{ value }}</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
</div> {# collapsable part #}
|
|
|
|
</div> {# per frame div #}
|
|
|
|
{% endwith %}
|
|
{% endfor %} {# frame #}
|
|
{# </div> #} {# per-exception div in the multi-exception case #}
|
|
|
|
{% if not forloop.last %}
|
|
<div class="italic pt-4">During handling of the above exception another exception occurred or was intentionally reraised:</div>
|
|
{# note: the above is specific to Python. We cannot distinguish between Python's 2 types of chained exceptions because the info is not sent by the client #}
|
|
{# we could try to infer this from the stacktrace, but parsing potentially arbitrarily formatted partial code is brittle #}
|
|
{% endif %}
|
|
|
|
{% endfor %}
|
|
|
|
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script src="{% static 'js/issue_stacktrace.js' %}"></script>
|
|
{% endblock %}
|