Skip to content

Commit

Permalink
Insert middleware to intercept Datahub connection exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
MatMoore committed May 23, 2024
1 parent 8fcb574 commit 3bc425b
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 8 deletions.
19 changes: 19 additions & 0 deletions core/middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import logging

from data_platform_catalogue.client.exceptions import ConnectivityError
from django.shortcuts import render

logger = logging.getLogger(__name__)


class CustomErrorMiddleware:
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
return self.get_response(request)

def process_exception(self, request, exception):
if isinstance(exception, ConnectivityError):
logger.exception(exception)
return render(request, "500_datahub_unavailable.html", status=500)
1 change: 1 addition & 0 deletions core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"core.middleware.CustomErrorMiddleware",
"django_prometheus.middleware.PrometheusAfterMiddleware",
]

Expand Down
5 changes: 0 additions & 5 deletions core/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

from django.contrib import admin
from django.urls import include, path
from django.views.generic import TemplateView


def trigger_error(request):
Expand All @@ -29,8 +28,4 @@ def trigger_error(request):
path("sentry-debug/", trigger_error),
path("", include("home.urls", namespace="home")),
path("", include("django_prometheus.urls")),
path(
"unavailable",
TemplateView.as_view(template_name="500_datahub_unavailable.html"),
),
]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from data_platform_catalogue.client.exceptions import (
AspectDoesNotExist,
CatalogueError,
ConnectivityError,
EntityDoesNotExist,
InvalidDomain,
ReferencedEntityMissing,
Expand Down Expand Up @@ -38,6 +38,7 @@
SearchResponse,
SortOption,
)
from datahub.configuration.common import ConfigurationError
from datahub.emitter import mce_builder
from datahub.emitter.mcp import MetadataChangeProposalWrapper
from datahub.ingestion.graph.client import DatahubClientConfig, DataHubGraph
Expand Down Expand Up @@ -110,12 +111,17 @@ def __init__(self, jwt_token, api_url: str, graph=None):
elif api_url.endswith("/api"):
self.gms_endpoint = api_url + "/gms"
else:
raise CatalogueError("api_url is incorrectly formatted")
raise ConnectivityError("api_url is incorrectly formatted")

self.server_config = DatahubClientConfig(
server=self.gms_endpoint, token=jwt_token
)
self.graph = graph or DataHubGraph(self.server_config)

try:
self.graph = graph or DataHubGraph(self.server_config)
except ConfigurationError as e:
raise ConnectivityError from e

self.search_client = SearchClient(self.graph)

self.dataset_query = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ class CatalogueError(Exception):
"""


class ConnectivityError(CatalogueError):
"""
Unable to collect to the Datahub catalog
"""


class ReferencedEntityMissing(CatalogueError):
"""
A referenced entity (such as a user or tag) does not yet exist when
Expand Down
Empty file added tests/core/__init__.py
Empty file.
27 changes: 27 additions & 0 deletions tests/core/test_middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from unittest.mock import MagicMock

from data_platform_catalogue.client.exceptions import ConnectivityError

from core.middleware import CustomErrorMiddleware


def test_middleware_renders_connectivity_response():
get_response = MagicMock()
request = MagicMock()
middleware = CustomErrorMiddleware(get_response)
error = ConnectivityError()
response = middleware.process_exception(request, error)

assert response
assert b"Catalogue service unavailable" in response.content
assert response.status_code == 500


def test_middleware_ignores_other_errors():
get_response = MagicMock()
request = MagicMock()
middleware = CustomErrorMiddleware(get_response)
error = Exception()
response = middleware.process_exception(request, error)

assert response is None

0 comments on commit 3bc425b

Please sign in to comment.