diff --git a/app/controllers/concerns/application_controller_multitenancy_concern.rb b/app/controllers/concerns/application_controller_multitenancy_concern.rb index a696f77fb89..75c5e6cb110 100644 --- a/app/controllers/concerns/application_controller_multitenancy_concern.rb +++ b/app/controllers/concerns/application_controller_multitenancy_concern.rb @@ -6,7 +6,16 @@ module ApplicationControllerMultitenancyConcern included do set_current_tenant_through_filter before_action :deduce_and_set_current_tenant - + helper_method :current_tenant + + rescue_from InstanceNotFoundError, with: :handle_instance_not_found + end + + protected + + def handle_instance_not_found(exception) + @exception = exception + render json: { error: 'Instance not found' }, status: :not_found end end diff --git a/app/controllers/concerns/application_multitenancy.rb b/app/controllers/concerns/application_multitenancy.rb index 89e3d1abe84..ddafa51bbc0 100644 --- a/app/controllers/concerns/application_multitenancy.rb +++ b/app/controllers/concerns/application_multitenancy.rb @@ -16,7 +16,7 @@ def deduce_tenant instance = Instance.find_tenant_by_host_or_default(tenant_host) if Rails.env.production? && instance.default? && instance.host.casecmp(tenant_host) != 0 - raise ActionController::RoutingError, 'Instance Not Found' + raise InstanceNotFoundError end instance diff --git a/client/app/api/ErrorHandling.ts b/client/app/api/ErrorHandling.ts index 8b32ec73adb..843eb8afbe6 100644 --- a/client/app/api/ErrorHandling.ts +++ b/client/app/api/ErrorHandling.ts @@ -2,6 +2,7 @@ import { AxiosResponse } from 'axios'; import { redirectToAuthPage, + redirectToBaseNotFound, redirectToForbidden, redirectToNotFound, } from 'lib/hooks/router/redirect'; @@ -23,6 +24,10 @@ const isComponentNotFoundResponse = (response?: AxiosResponse): boolean => response?.status === 404 && response.data?.error?.toLowerCase().includes('component not found'); // NOTE: This string is taken from BE's handle_component_not_found +const isInstanceNotFoundResponse = (response?: AxiosResponse): boolean => + response?.status === 404 && + response.data?.error?.toLowerCase().includes('instance not found'); // NOTE: This string is taken from BE's handle_component_not_found + export const redirectIfMatchesErrorIn = (response?: AxiosResponse): void => { if (isUnauthenticatedResponse(response)) { localStorage.clear(); @@ -32,4 +37,5 @@ export const redirectIfMatchesErrorIn = (response?: AxiosResponse): void => { // Should open a new window and login redirectToForbidden(); if (isComponentNotFoundResponse(response)) redirectToNotFound(); + if (isInstanceNotFoundResponse(response)) redirectToBaseNotFound(); }; diff --git a/client/app/lib/hooks/router/redirect.tsx b/client/app/lib/hooks/router/redirect.tsx index cb30df11f34..6723cf1c48c 100644 --- a/client/app/lib/hooks/router/redirect.tsx +++ b/client/app/lib/hooks/router/redirect.tsx @@ -66,6 +66,13 @@ export const redirectToNotFound = (): void => { window.location.href = '/404'; }; +export const redirectToBaseNotFound = (): void => { + const url = new URL(window.location.href); + url.host = window.location.hostname.split('.').slice(-2).join('.'); + url.pathname = '/404'; + window.location.href = url.toString(); +}; + export const getForbiddenSourceURL = (rawURL: string): string | null => { const url = new URL(rawURL); return url.searchParams.get(FORBIDDEN_SOURCE_URL_SEARCH_PARAM); diff --git a/lib/autoload/instance_not_found_error.rb b/lib/autoload/instance_not_found_error.rb new file mode 100644 index 00000000000..72364b7eb55 --- /dev/null +++ b/lib/autoload/instance_not_found_error.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +class InstanceNotFoundError < StandardError + def initialize(message = nil) + super(message || 'Instance not found') + end +end