Skip to content

Commit

Permalink
[#2843] Refactor error handling for vragen/aanvragen list views
Browse files Browse the repository at this point in the history
    - instead of passing silently over errors which occurred when
      trying to fetch vragen/aanvragen, we re-raise the exception
      and display an informative message to the user
    - custom exceptions are introduced for the klanten and zaken
      services
  • Loading branch information
pi-sigma committed Oct 31, 2024
1 parent 5e2afe4 commit b6ce4ae
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 29 deletions.
5 changes: 3 additions & 2 deletions src/open_inwoner/accounts/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from open_inwoner.haalcentraal.models import HaalCentraalConfig
from open_inwoner.haalcentraal.utils import update_brp_data_in_db
from open_inwoner.openklant.exceptions import KlantenServiceError
from open_inwoner.openklant.models import OpenKlant2Config
from open_inwoner.openklant.services import OpenKlant2Service, eSuiteKlantenService
from open_inwoner.utils.logentry import user_action
Expand Down Expand Up @@ -42,7 +43,7 @@ def update_user_from_klant_on_login(sender, user, request, *args, **kwargs):
if use_ok2 and (openklant2_config := OpenKlant2Config.from_django_settings()):
try:
service = OpenKlant2Service(config=openklant2_config)
except RuntimeError:
except KlantenServiceError:
logger.error("OpenKlant2 service failed to build")
return

Expand All @@ -58,7 +59,7 @@ def update_user_from_klant_on_login(sender, user, request, *args, **kwargs):
# eSuite
try:
service = eSuiteKlantenService()
except RuntimeError:
except KlantenServiceError:
logger.error("eSuiteKlantenService failed to build")
return

Expand Down
20 changes: 17 additions & 3 deletions src/open_inwoner/accounts/views/contactmoments.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from datetime import datetime
from typing import TypedDict

from django.contrib import messages
from django.contrib.auth.mixins import AccessMixin
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import redirect
Expand All @@ -12,6 +13,7 @@
from django.views.generic import TemplateView

from glom import glom
from requests.exceptions import RequestException
from view_breadcrumbs import BaseBreadcrumbMixin

from open_inwoner.openklant.api_models import KlantContactMoment
Expand All @@ -35,6 +37,7 @@
)
from open_inwoner.openzaak.clients import MultiZgwClientProxy
from open_inwoner.openzaak.models import ZGWApiGroupConfig
from open_inwoner.utils.api import ClientError
from open_inwoner.utils.mixins import PaginationMixin
from open_inwoner.utils.views import CommonPageMixin

Expand Down Expand Up @@ -175,9 +178,20 @@ def get_anchors(self) -> list:
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)

kcms = fetch_klantcontactmomenten(
**get_fetch_parameters(self.request, use_vestigingsnummer=True)
)
try:
kcms = fetch_klantcontactmomenten(
**get_fetch_parameters(self.request, use_vestigingsnummer=True)
)
# TODO: replace with custom exception when openklant refactor is done
except (RequestException, ClientError):
kcms = []
messages.add_message(
self.request,
messages.ERROR,
_(
"Het was niet mogelijk om uw vragen op te halen, probeer het later nog eens"
),
)

klant_config = OpenKlantConfig.get_solo()
if exclude_range := klant_config.exclude_contactmoment_kanalen:
Expand Down
3 changes: 2 additions & 1 deletion src/open_inwoner/accounts/views/mixins.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging

from open_inwoner.openklant.exceptions import KlantenServiceError
from open_inwoner.openklant.models import OpenKlantConfig
from open_inwoner.openklant.services import eSuiteKlantenService

Expand All @@ -13,7 +14,7 @@ def patch_klant(self, update_data: dict):

try:
service = eSuiteKlantenService(config=OpenKlantConfig.get_solo())
except RuntimeError:
except KlantenServiceError:
logger.error("Error building KlantenService")
return

Expand Down
5 changes: 3 additions & 2 deletions src/open_inwoner/accounts/views/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.dispatch import receiver

from open_inwoner.accounts.models import User
from open_inwoner.openklant.exceptions import KlantenServiceError
from open_inwoner.openklant.models import OpenKlant2Config
from open_inwoner.openklant.services import OpenKlant2Service, eSuiteKlantenService

Expand All @@ -28,7 +29,7 @@ def get_or_create_klant_for_new_user(
if use_ok2 and (openklant2_config := OpenKlant2Config.from_django_settings()):
try:
service = OpenKlant2Service(config=openklant2_config)
except RuntimeError:
except KlantenServiceError:
logger.error("OpenKlant2 service failed to build")
return

Expand All @@ -53,7 +54,7 @@ def get_or_create_klant_for_new_user(
# eSuite
try:
service = eSuiteKlantenService()
except RuntimeError:
except KlantenServiceError:
logger.error("eSuiteKlantenService failed to build")
return

Expand Down
17 changes: 15 additions & 2 deletions src/open_inwoner/cms/cases/views/cases.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
from typing import Sequence

from django.contrib import messages
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
Expand All @@ -15,6 +16,7 @@
from open_inwoner.utils.mixins import PaginationMixin
from open_inwoner.utils.views import CommonPageMixin

from .exceptions import ZakenServiceError
from .mixins import CaseAccessMixin, CaseLogMixin, OuterCaseAccessMixin
from .services import CaseFilterFormOption, CaseListService

Expand Down Expand Up @@ -70,8 +72,19 @@ def get_context_data(self, **kwargs):
context["filter_form_enabled"] = config.zaken_filter_enabled

# update ctx with open submissions and cases (possibly fitered)
open_submissions: Sequence[UniformCase] = case_service.get_submissions()
preprocessed_cases: Sequence[UniformCase] = case_service.get_cases()
open_submissions = []
preprocessed_cases = []
try:
open_submissions: Sequence[UniformCase] = case_service.get_submissions()
preprocessed_cases: Sequence[UniformCase] = case_service.get_cases()
except ZakenServiceError:
messages.add_message(
self.request,
messages.ERROR,
_(
"Het was niet mogelijk om uw anvragen op te halen, probeer het later nog eens"
),
)

if config.zaken_filter_enabled:
case_status_frequencies = case_service.get_case_status_frequencies()
Expand Down
2 changes: 2 additions & 0 deletions src/open_inwoner/cms/cases/views/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class ZakenServiceError(Exception):
pass
4 changes: 4 additions & 0 deletions src/open_inwoner/cms/cases/views/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
)
from open_inwoner.openzaak.utils import get_user_fetch_parameters, is_zaak_visible

from .exceptions import ZakenServiceError

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -131,6 +133,7 @@ def get_submissions(self) -> list[SubmissionWithApiGroup]:
)
except BaseException:
logger.exception("Error fetching and pre-processing cases")
raise ZakenServiceError

# Sort submissions by date modified
subs_with_api_group.sort(
Expand Down Expand Up @@ -184,6 +187,7 @@ def get_cases(self) -> list[ZaakWithApiGroup]:
"Error while fetching and pre-processing cases for API group %s",
group_for_task,
)
raise

# Ensure stable sorting for pagination and testing purposes
cases_with_api_group.sort(key=lambda c: all_api_groups.index(c.api_group))
Expand Down
19 changes: 14 additions & 5 deletions src/open_inwoner/cms/cases/views/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from zgw_consumers.api_models.constants import RolOmschrijving

from open_inwoner.mail.service import send_contact_confirmation_mail
from open_inwoner.openklant.exceptions import KlantenServiceError
from open_inwoner.openklant.models import OpenKlantConfig
from open_inwoner.openklant.services import eSuiteKlantenService, eSuiteVragenService
from open_inwoner.openklant.wrap import (
Expand Down Expand Up @@ -165,14 +166,22 @@ def get_context_data(self, **kwargs):
# questions/E-suite contactmomenten
try:
service = eSuiteVragenService(config=openklant_config)
except RuntimeError:
logger.error("Failed to build eSuiteVragenService")
objectcontactmomenten = []
else:
objectcontactmomenten = service.retrieve_objectcontactmomenten_for_zaak(
self.case
)

except KlantenServiceError:
logger.error(
"There was a problem fetching objectcontactmomenten with eSuiteVragenService for %s"
% self.case
)
objectcontactmomenten = []
messages.add_message(
self.request,
messages.ERROR,
_(
"Het was niet mogelijk om uw vragen op te halen, probeer het later nog eens"
),
)
questions = []
for ocm in objectcontactmomenten:
question = getattr(ocm, "contactmoment", None)
Expand Down
6 changes: 3 additions & 3 deletions src/open_inwoner/openklant/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def retrieve_klanten_for_bsn(self, user_bsn: str) -> list[Klant]:
all_data = list(pagination_helper(self, data))
except (RequestException, ClientError) as e:
logger.exception("exception while making request", exc_info=e)
return []
raise

klanten = factory(Klant, all_data)

Expand All @@ -139,7 +139,7 @@ def retrieve_klanten_for_kvk_or_rsin(
all_data = list(pagination_helper(self, data))
except (RequestException, ClientError) as e:
logger.exception("exception while making request", exc_info=e)
return []
raise

klanten = factory(Klant, all_data)

Expand Down Expand Up @@ -243,7 +243,7 @@ def retrieve_objectcontactmomenten_for_zaak(
all_data = list(pagination_helper(self, data))
except (RequestException, ClientError) as exc:
logger.exception("exception while making request", exc_info=exc)
return []
raise

object_contact_momenten = factory(ObjectContactMoment, all_data)

Expand Down
2 changes: 2 additions & 0 deletions src/open_inwoner/openklant/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class KlantenServiceError(Exception):
pass
25 changes: 16 additions & 9 deletions src/open_inwoner/openklant/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
KlantCreateData,
ObjectContactMoment,
)
from open_inwoner.openklant.exceptions import KlantenServiceError
from open_inwoner.openklant.models import OpenKlant2Config, OpenKlantConfig
from open_inwoner.openzaak.api_models import Zaak
from open_inwoner.utils.api import ClientError, get_json_response
Expand Down Expand Up @@ -97,17 +98,19 @@ class eSuiteKlantenService(KlantenService):
def __init__(self, config: OpenKlantConfig | None = None):
self.config = config or OpenKlantConfig.get_solo()
if not self.config:
raise RuntimeError("eSuiteKlantenService instance needs a configuration")
raise KlantenServiceError(
"eSuiteKlantenService instance needs a configuration"
)

self.service_config = self.config.klanten_service
if not self.service_config:
raise RuntimeError(
raise KlantenServiceError(
"eSuiteKlantenService instance needs a servivce configuration"
)

self.client = build_zgw_client(service=self.service_config)
if not self.client:
raise RuntimeError("eSuiteKlantenService instance needs a client")
raise KlantenServiceError("eSuiteKlantenService instance needs a client")

def get_or_create_klant(
self, fetch_params: FetchParameters, user: User
Expand Down Expand Up @@ -312,17 +315,19 @@ class eSuiteVragenService(KlantenService):
def __init__(self, config: OpenKlantConfig | None = None):
self.config = config or OpenKlantConfig.get_solo()
if not self.config:
raise RuntimeError("eSuiteVragenService instance needs a configuration")
raise KlantenServiceError(
"eSuiteVragenService instance needs a configuration"
)

self.service_config = self.config.contactmomenten_service
if not self.service_config:
raise RuntimeError(
raise KlantenServiceError(
"eSuiteVragenService instance needs a servivce configuration"
)

self.client = build_zgw_client(service=self.service_config)
if not self.client:
raise RuntimeError("eSuiteVragenService instance needs a client")
raise KlantenServiceError("eSuiteVragenService instance needs a client")

#
# contactmomenten
Expand Down Expand Up @@ -430,7 +435,7 @@ def retrieve_objectcontactmomenten_for_zaak(
all_data = list(pagination_helper(self, data))
except (RequestException, ClientError) as exc:
logger.exception("exception while making request", exc_info=exc)
return []
raise KlantenServiceError

object_contact_momenten = factory(ObjectContactMoment, all_data)

Expand Down Expand Up @@ -550,7 +555,9 @@ class OpenKlant2Service(KlantenService):
def __init__(self, config: OpenKlant2Config | None = None):
self.config = config or OpenKlant2Config.from_django_settings()
if not self.config:
raise RuntimeError("OpenKlant2Service instance needs a configuration")
raise KlantenServiceError(
"OpenKlant2Service instance needs a configuration"
)

self.client = OpenKlant2Client(
base_url=self.config.api_url,
Expand All @@ -559,7 +566,7 @@ def __init__(self, config: OpenKlant2Config | None = None):
},
)
if not self.client:
raise RuntimeError("OpenKlant2Service instance needs a client")
raise KlantenServiceError("OpenKlant2Service instance needs a client")

if mijn_vragen_actor := getattr(config, "mijn_vragen_actor", None):
self.mijn_vragen_actor = (
Expand Down
2 changes: 1 addition & 1 deletion src/open_inwoner/openzaak/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def fetch_cases_by_bsn(
headers=CRS_HEADERS,
)
)
except (RequestException, ClientError) as e:
except (RequestException, ClientError, Exception) as e:
logger.exception("exception while making request", exc_info=e)
return []

Expand Down
8 changes: 7 additions & 1 deletion src/open_inwoner/templates/pages/cases/list_inner.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{% load link_tags button_tags i18n grid_tags icon_tags list_tags pagination_tags utils %}
{% load link_tags button_tags i18n grid_tags icon_tags list_tags notification_tags pagination_tags utils %}

{% block notifications %}
<div class="container container--no-margin">
{% notifications messages closable=True %}
</div>
{% endblock %}

<h1 class="utrecht-heading-1" id="cases">{{ page_title }} ({{ paginator.count }})</h1>
<p class="utrecht-paragraph utrecht-paragraph--oip utrecht-paragraph--oip-title-text">{{ title_text }}</p>
Expand Down

0 comments on commit b6ce4ae

Please sign in to comment.