diff --git a/events/utils.py b/events/utils.py index d8ea8a6..12b2f5c 100644 --- a/events/utils.py +++ b/events/utils.py @@ -1,3 +1,4 @@ +from os.path import basename from datetime import datetime, timezone from uuid import UUID import json @@ -165,3 +166,28 @@ def apply_sourcemaps(event_data): frame['filename'] = token.src frame['function'] = token.name # frame["colno"] = token.src_col + TO_DISPLAY not actually used + + +def get_sourcemap_images(event_data): + # NOTE: butchered copy/paste of apply_sourcemaps; refactoring for DRY is a TODO + images = event_data.get("debug_meta", {}).get("images", []) + if not images: + return [] + + debug_id_for_filename = { + image["code_file"]: UUID(image["debug_id"]) + for image in images + if "debug_id" in image and "code_file" in image and image["type"] == "sourcemap" + } + + metadata_obj_lookup = { + metadata_obj.debug_id: metadata_obj + for metadata_obj in FileMetadata.objects.filter( + debug_id__in=debug_id_for_filename.values(), file_type="source_map").select_related("file") + } + + return [ + (basename(filename), + f"{debug_id} " + (" (uploaded)" if debug_id in metadata_obj_lookup else " (not uploaded)")) + for filename, debug_id in debug_id_for_filename.items() + ] diff --git a/issues/templates/issues/event_details.html b/issues/templates/issues/event_details.html index 42efa54..249f9bb 100644 --- a/issues/templates/issues/event_details.html +++ b/issues/templates/issues/event_details.html @@ -203,6 +203,19 @@ the fact that we commented-out rather than clobbered reveals a small amount of d {% endif %} +{% if sourcemaps_images %} +

Sourcemap IDs

+ +
+ {% for key, value in sourcemaps_images %} +
+
{{ key }}
+
{{ value|linebreaks }}
+
+ {% endfor %} +
+{% endif %} + {% if parsed_data.extra %}

Extra

diff --git a/issues/views.py b/issues/views.py index d547a17..5d19031 100644 --- a/issues/views.py +++ b/issues/views.py @@ -35,7 +35,7 @@ from tags.search import search_issues, search_events, search_events_optimized from .models import Issue, IssueQuerysetStateManager, IssueStateManager, TurningPoint, TurningPointKind from .forms import CommentForm from .utils import get_values, get_main_exception -from events.utils import annotate_with_meta, apply_sourcemaps +from events.utils import annotate_with_meta, apply_sourcemaps, get_sourcemap_images logger = logging.getLogger("bugsink.issues") @@ -658,6 +658,15 @@ def issue_event_details(request, issue, event_pk=None, digest_order=None, nav=No contexts = get_contexts_enriched_with_ua(parsed_data) + try: + sourcemaps_images = get_sourcemap_images(parsed_data) + except Exception as e: + if settings.DEBUG or settings.I_AM_RUNNING == "TEST": + # when developing/testing, I _do_ want to get notified + raise + # sourcemaps are still experimental; we don't want to fail on them, so we just log the error and move on. + capture_or_log_exception(e, logger) + return render(request, "issues/event_details.html", { "tab": "event-details", "this_view": "event_details", @@ -671,6 +680,7 @@ def issue_event_details(request, issue, event_pk=None, digest_order=None, nav=No "logentry_info": logentry_info, "deployment_info": deployment_info, "contexts": contexts, + "sourcemaps_images": sourcemaps_images, "mute_options": GLOBAL_MUTE_OPTIONS, "q": request.GET.get("q", ""), # event_qs_count is not used when there is no q, so no need to calculate it in that case