diff --git a/client/src/components/Tool/ToolHelpForum.vue b/client/src/components/Tool/ToolHelpForum.vue index 912b417a425f..49589dec8604 100644 --- a/client/src/components/Tool/ToolHelpForum.vue +++ b/client/src/components/Tool/ToolHelpForum.vue @@ -6,10 +6,12 @@ import { computed, onMounted, ref } from "vue"; import { GalaxyApi } from "@/api"; import { galaxyLogo } from "@/components/icons/galaxyIcons"; import { useConfigStore } from "@/stores/configurationStore"; +import { errorMessageAsString } from "@/utils/simple-error"; import { getShortToolId } from "@/utils/tool"; import { createTopicUrl, type HelpForumPost, type HelpForumTopic, useHelpURLs } from "./helpForumUrls"; +import Alert from "@/components/Alert.vue"; import Heading from "@/components/Common/Heading.vue"; import ExternalLink from "@/components/ExternalLink.vue"; @@ -22,6 +24,7 @@ const toolHelpTag = "tool-help"; const topics = ref([]); const posts = ref([]); +const errorMessage = ref(""); const helpAvailable = computed(() => topics.value.length > 0); const root = ref(null); @@ -36,7 +39,7 @@ onMounted(async () => { }, }); if (error) { - console.error("Error fetching help forum data", error); + errorMessage.value = errorMessageAsString(error, "Failed to search the Help Forum."); } topics.value = data?.topics ?? []; @@ -66,12 +69,14 @@ const configStore = useConfigStore();
Help Forum + +

Following questions on the Help Forum may be related to this tool:

-

+

There are no questions on the Help Forum about this tool. diff --git a/lib/galaxy/webapps/galaxy/services/help.py b/lib/galaxy/webapps/galaxy/services/help.py index e75bf087e685..279fcd3c7439 100644 --- a/lib/galaxy/webapps/galaxy/services/help.py +++ b/lib/galaxy/webapps/galaxy/services/help.py @@ -1,7 +1,12 @@ import logging from galaxy.config import GalaxyAppConfiguration -from galaxy.exceptions import ServerNotConfiguredForRequest +from galaxy.exceptions import ( + GatewayTimeoutException, + InternalServerError, + ServerNotConfiguredForRequest, + UpstreamProxyError, +) from galaxy.schema.help import HelpForumSearchResponse from galaxy.security.idencoding import IdEncodingHelper from galaxy.util import requests @@ -34,10 +39,49 @@ def search_forum(self, query: str) -> HelpForumSearchResponse: if not self.config.help_forum_api_url: raise ServerNotConfiguredForRequest("Help forum API URL is not configured.") forum_search_url = f"{self.config.help_forum_api_url}/search.json" - response = requests.get( - url=forum_search_url, - params={ - "q": query, - }, - ) - return HelpForumSearchResponse(**response.json()) + try: + response = requests.get( + url=forum_search_url, + params={ + "q": query, + }, + ) + except requests.exceptions.ConnectionError as e: + log.error("Could not connect to the Galaxy Help Forum at %s: %s", forum_search_url, e) + raise UpstreamProxyError( + "Could not connect to the Galaxy Help Forum. The service may be temporarily unavailable." + ) + except requests.exceptions.Timeout as e: + log.error("Request to the Galaxy Help Forum at %s timed out: %s", forum_search_url, e) + raise GatewayTimeoutException("The request to the Galaxy Help Forum timed out. Please try again later.") + except requests.exceptions.RequestException as e: + log.error("Unexpected error requesting the Galaxy Help Forum at %s: %s", forum_search_url, e) + raise InternalServerError(f"An error occurred while requesting the Galaxy Help Forum: {e}") + + if not response.ok: + if 400 <= response.status_code < 500: + log.error( + "The Galaxy Help Forum returned a client error (HTTP %d) from %s. " + "This likely indicates a misconfigured URL or API key.", + response.status_code, + forum_search_url, + ) + raise InternalServerError( + f"The Galaxy Help Forum returned an error (HTTP {response.status_code}). " + "This may indicate a misconfigured URL or API key that requires admin intervention." + ) + else: + log.error( + "The Galaxy Help Forum returned a server error (HTTP %d) from %s", + response.status_code, + forum_search_url, + ) + raise UpstreamProxyError( + f"The Galaxy Help Forum returned an error (HTTP {response.status_code}). " + "The service may be temporarily unavailable. Please try again later." + ) + + try: + return HelpForumSearchResponse(**response.json()) + except ValueError as e: + raise InternalServerError(f"Received an unexpected response format from the Galaxy Help Forum: {e}")