diff --git a/src/servala/core/models/organization.py b/src/servala/core/models/organization.py
index a9dcd4e..da8c11b 100644
--- a/src/servala/core/models/organization.py
+++ b/src/servala/core/models/organization.py
@@ -4,6 +4,7 @@ from django.conf import settings
from django.db import models, transaction
from django.utils.functional import cached_property
from django.utils.text import slugify
+from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from django_scopes import ScopedManager, scopes_disabled
@@ -74,6 +75,12 @@ class Organization(ServalaModelMixin, models.Model):
user=user, organization=self, role=OrganizationRole.OWNER
)
+ def add_support_message(self, message):
+ support_message = _(
+ "Need help? We're happy to help via the support form."
+ ).format(support_url=self.urls.support)
+ return mark_safe(f"{message} {support_message}")
+
@classmethod
@transaction.atomic
def create_organization(cls, instance, owner):
diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py
index ebc2878..365fcce 100644
--- a/src/servala/core/models/service.py
+++ b/src/servala/core/models/service.py
@@ -20,10 +20,6 @@ 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):
"""
@@ -620,10 +616,8 @@ class ServiceInstance(ServalaModelMixin, models.Model):
context=context,
)
except IntegrityError:
- raise cls._format_error_with_support(
- "An instance with this name already exists in this organization. Please choose a different name.",
- organization,
- )
+ message = "An instance with this name already exists in this organization. Please choose a different name."
+ raise ValidationError(organization.add_support_message(message))
try:
spec_data = cls._prepare_spec_data(spec_data)
@@ -661,16 +655,13 @@ class ServiceInstance(ServalaModelMixin, models.Model):
try:
error_body = json.loads(e.body)
reason = error_body.get("message", str(e))
- raise cls._format_error_with_support(
- "Kubernetes API error: {error}.", organization, error=reason
- )
+ message = f"Kubernetes API error: {reason}."
+ raise ValidationError(organization.add_support_message(message))
except (ValueError, TypeError):
- 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)
- )
+ message = f"Kubernetes API error: {str(e)}."
+ raise ValidationError(organization.add_support_message(message))
+ message = f"Error creating instance: {str(e)}."
+ raise ValidationError(organization.add_support_message(message))
return instance
def update_spec(self, spec_data, updated_by):
@@ -691,28 +682,19 @@ class ServiceInstance(ServalaModelMixin, models.Model):
self.save() # Updates updated_at timestamp
except ApiException as e:
if e.status == 404:
- raise self._format_error_with_support(
- "Service instance not found in Kubernetes. It may have been deleted externally.",
- self.organization,
- )
+ message = "Service instance not found in Kubernetes. It may have been deleted externally."
+ raise ValidationError(self.organization.add_support_message(message))
try:
error_body = json.loads(e.body)
reason = error_body.get("message", str(e))
- raise self._format_error_with_support(
- "Kubernetes API error updating instance: {error}.",
- self.organization,
- error=reason,
- )
+ message = f"Kubernetes API error updating instance: {reason}."
+ raise ValidationError(self.organization.add_support_message(message))
except (ValueError, TypeError):
- raise self._format_error_with_support(
- "Kubernetes API error updating instance: {error}.",
- self.organization,
- error=str(e),
- )
+ message = f"Kubernetes API error updating instance: {str(e)}."
+ raise ValidationError(self.organization.add_support_message(message))
except Exception as e:
- raise self._format_error_with_support(
- "Error updating instance: {error}.", self.organization, error=str(e)
- )
+ message = f"Error updating instance: {str(e)}."
+ raise ValidationError(self.organization.add_support_message(message))
@transaction.atomic
def delete_instance(self, user):
@@ -863,24 +845,3 @@ 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/views/mixins.py b/src/servala/frontend/views/mixins.py
index 7e7b453..fd5a494 100644
--- a/src/servala/frontend/views/mixins.py
+++ b/src/servala/frontend/views/mixins.py
@@ -1,14 +1,9 @@
from django.utils.functional import cached_property
-from django.utils.safestring import mark_safe
-from django.utils.translation import gettext_lazy as _
from django.views.generic import UpdateView
from rules.contrib.views import AutoPermissionRequiredMixin, PermissionRequiredMixin
from servala.core.models import Organization
-# Import the support message template from the service model
-from servala.core.models.service import SUPPORT_MESSAGE_TEMPLATE
-
class HtmxViewMixin:
fragments = []
@@ -95,22 +90,3 @@ class OrganizationViewMixin(PermissionRequiredMixin):
def has_permission(self):
return self.has_organization_permission() and super().has_permission()
-
- def format_error_with_support(self, message, **kwargs):
- """
- Helper method to format error messages with support links for frontend views.
-
- Args:
- message: The error message template (without support text)
- **kwargs: Additional format parameters for the message
-
- Returns:
- A formatted message with support link
- """
- support_url = self.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 mark_safe(full_message)
diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py
index 49ac683..be1b80c 100644
--- a/src/servala/frontend/views/service.py
+++ b/src/servala/frontend/views/service.py
@@ -146,7 +146,7 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
if not form: # Should not happen if context_object is valid, but as a safeguard
messages.error(
self.request,
- self.format_error_with_support("Could not initialize service form."),
+ self.organization.add_support_message("Could not initialize service form."),
)
return self.render_to_response(context)
@@ -165,8 +165,8 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
except Exception as e:
messages.error(
self.request,
- self.format_error_with_support(
- "Error creating instance: {error}.", error=str(e)
+ self.organization.add_support_message(
+ f"Error creating instance: {str(e)}."
),
)
@@ -373,8 +373,8 @@ class ServiceInstanceUpdateView(
except Exception as e:
messages.error(
self.request,
- self.format_error_with_support(
- "Error updating instance: {error}.", error=str(e)
+ self.organization.add_support_message(
+ f"Error updating instance: {str(e)}."
),
)
return self.form_invalid(form)
@@ -444,10 +444,8 @@ class ServiceInstanceDeleteView(
except Exception as e:
messages.error(
self.request,
- self.format_error_with_support(
- "An error occurred while trying to delete instance '{name}': {error}.",
- name=self.object.name,
- error=str(e),
+ self.organization.add_support_message(
+ f"An error occurred while trying to delete instance '{self.object.name}': {str(e)}."
),
)
response = HttpResponse()