From 12e3d47600094f7c95abfb0797151fc3016715b4 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 2 Mar 2026 11:04:51 +0000 Subject: [PATCH] Enhance logging configuration in WSGI setup for better debugging and error handling --- atlas/views.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++--- rad/wsgi.py | 4 ++- 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/atlas/views.py b/atlas/views.py index cf62fb53..b1db82aa 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -4800,6 +4800,11 @@ def series_dicom_json(request, pk): def series_tags_partial(request, pk): + logger.info(f"Fetching tags for series {pk}") + try: + print(f"series_tags_partial hit: {pk}") + except Exception: + pass # Accept either a numeric PK or a SeriesInstanceUID string series = None try: @@ -4809,18 +4814,78 @@ def series_tags_partial(request, pk): series = None if series is None: + # Try exact match first series = Series.objects.filter(series_instance_uid=pk).first() if series is None: - return HttpResponse(status=404) - images = list(series.images.all()) + # Try URL-decoded value and stripped variants + try: + import urllib.parse + + decoded = urllib.parse.unquote(pk) + except Exception: + decoded = pk + + if decoded != pk: + series = Series.objects.filter(series_instance_uid=decoded).first() + + if series is None: + # Fallback to contains (be permissive for slightly mangled UIDs) + try: + series = Series.objects.filter(series_instance_uid__contains=pk).first() + except Exception: + series = None + + images = None + if series is not None: + images = list(series.images.all()) + else: + # If no Series exists yet, try to find uploaded uncategorised dicoms + try: + dicoms = UncategorisedDicom.objects.filter(series_instance_uid=pk) + except Exception: + dicoms = UncategorisedDicom.objects.none() + + if not dicoms.exists(): + try: + import urllib.parse + + decoded = urllib.parse.unquote(pk) + except Exception: + decoded = pk + + if decoded != pk: + dicoms = UncategorisedDicom.objects.filter(series_instance_uid=decoded) + + if not dicoms.exists(): + try: + dicoms = UncategorisedDicom.objects.filter(series_instance_uid__contains=pk) + except Exception: + dicoms = UncategorisedDicom.objects.none() + + if not dicoms.exists(): + return HttpResponse(status=404) + + images = list(dicoms) num_images = len(images) tag_values = {} tag_counts = {} for img in images: - ds = img.get_dicom_data() + # Uploaded uncategorised dicoms use a different API than SeriesImage + try: + if isinstance(img, UncategorisedDicom): + try: + ds = pydicom.dcmread(img.image) + except Exception: + # skip invalid dicoms + continue + else: + ds = img.get_dicom_data() + except Exception: + # Defensive: skip items that don't expose expected methods + continue if not ds: continue # Iterate elements diff --git a/rad/wsgi.py b/rad/wsgi.py index 78186fbb..276954d4 100644 --- a/rad/wsgi.py +++ b/rad/wsgi.py @@ -34,12 +34,14 @@ try: enqueue=True, serialize=True, ) + logger.debug("Loguru logging configured with stdout and file sinks") except Exception: # Best-effort only — don't crash WSGI startup if logging can't be configured try: - logger.add(sys.stderr) + logger.add(sys.stderr, level="DEBUG", enqueue=True, backtrace=False, diagnose=False) except Exception: pass + logger.debug("Failed to configure Loguru logging sinks, continuing without file logging") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rad.settings")