diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 362661b..ebc2878 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -10,6 +10,7 @@ from django.core.exceptions import ValidationError from django.db import IntegrityError, models, transaction from django.utils import timezone from django.utils.functional import cached_property +from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ from encrypted_fields.fields import EncryptedJSONField from kubernetes import client, config @@ -19,6 +20,10 @@ from servala.core import rules as perms from servala.core.models.mixins import ServalaModelMixin from servala.core.validators import kubernetes_name_validator +SUPPORT_MESSAGE_TEMPLATE = _( + "Need help? We're happy to help via the support form." +) + class ServiceCategory(ServalaModelMixin, models.Model): """ @@ -615,10 +620,9 @@ class ServiceInstance(ServalaModelMixin, models.Model): context=context, ) except IntegrityError: - raise ValidationError( - _( - "An instance with this name already exists in this organization. Please choose a different name." - ) + raise cls._format_error_with_support( + "An instance with this name already exists in this organization. Please choose a different name.", + organization, ) try: @@ -657,10 +661,16 @@ class ServiceInstance(ServalaModelMixin, models.Model): try: error_body = json.loads(e.body) reason = error_body.get("message", str(e)) - raise ValidationError(_("Kubernetes API error: {}").format(reason)) + raise cls._format_error_with_support( + "Kubernetes API error: {error}.", organization, error=reason + ) except (ValueError, TypeError): - raise ValidationError(_("Kubernetes API error: {}").format(str(e))) - raise ValidationError(_("Error creating instance: {}").format(str(e))) + raise cls._format_error_with_support( + "Kubernetes API error: {error}.", organization, error=str(e) + ) + raise cls._format_error_with_support( + "Error creating instance: {error}.", organization, error=str(e) + ) return instance def update_spec(self, spec_data, updated_by): @@ -681,28 +691,27 @@ class ServiceInstance(ServalaModelMixin, models.Model): self.save() # Updates updated_at timestamp except ApiException as e: if e.status == 404: - raise ValidationError( - _( - "Service instance not found in Kubernetes. It may have been deleted externally." - ) + raise self._format_error_with_support( + "Service instance not found in Kubernetes. It may have been deleted externally.", + self.organization, ) try: error_body = json.loads(e.body) reason = error_body.get("message", str(e)) - raise ValidationError( - _("Kubernetes API error updating instance: {error}").format( - error=reason - ) + raise self._format_error_with_support( + "Kubernetes API error updating instance: {error}.", + self.organization, + error=reason, ) except (ValueError, TypeError): - raise ValidationError( - _("Kubernetes API error updating instance: {error}").format( - error=str(e) - ) + raise self._format_error_with_support( + "Kubernetes API error updating instance: {error}.", + self.organization, + error=str(e), ) except Exception as e: - raise ValidationError( - _("Error updating instance: {error}").format(error=str(e)) + raise self._format_error_with_support( + "Error updating instance: {error}.", self.organization, error=str(e) ) @transaction.atomic @@ -854,3 +863,24 @@ class ServiceInstance(ServalaModelMixin, models.Model): return {"error": str(e)} except Exception as e: return {"error": str(e)} + + @classmethod + def _format_error_with_support(cls, message, organization, **kwargs): + """ + Helper method to format error messages with support links. + + Args: + message: The error message template (without support text) + organization: The organization object to get the support URL + **kwargs: Additional format parameters for the message + + Returns: + A ValidationError with the formatted message including support link + """ + support_url = organization.urls.support + # Combine the main message with the support message template + full_message = _("{message} {support_message}").format( + message=_(message).format(**kwargs), + support_message=SUPPORT_MESSAGE_TEMPLATE.format(support_url=support_url), + ) + return ValidationError(mark_safe(full_message)) diff --git a/src/servala/frontend/templates/includes/message.html b/src/servala/frontend/templates/includes/message.html index 59260d2..d5debc9 100644 --- a/src/servala/frontend/templates/includes/message.html +++ b/src/servala/frontend/templates/includes/message.html @@ -9,7 +9,7 @@