From ee426088f7ffec1997c7ba6afbd3ecb5fc9a891f Mon Sep 17 00:00:00 2001 From: Magnus-SmariSma <20734986-Magnus-SmariSma@users.noreply.replit.com> Date: Thu, 20 Mar 2025 23:11:49 +0000 Subject: [PATCH] Hardcode IUCN API v4 endpoint and remove v3 API check. Improve error handling and messaging. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e931b5ab-041b-42e7-baf1-50017869cef6 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/e19c6a51-7e4c-4bb8-a6a6-46dc00f0ec99/c86608db-9b9f-432d-9898-0faedcc6199e.jpg --- server/routes.ts | 144 ++++++++++++++++------------------------------- 1 file changed, 48 insertions(+), 96 deletions(-) diff --git a/server/routes.ts b/server/routes.ts index e44d953..a1371b3 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -304,79 +304,46 @@ export async function registerRoutes(app: Express): Promise { } }); - // IUCN API Status check endpoint + // IUCN API Status check endpoint - v4 only app.get("/api/iucn/status", async (req: Request, res: Response) => { try { - // Try V4 API first (with bearer token) const activeToken = await storage.getActiveToken(); - if (activeToken?.iucnToken) { - try { - // Use a simpler endpoint to check if the API is working - we'll just ping the version endpoint - const versionUrl = `${IUCN_V4_BASE_URL}/version`; - - const response = await axios.get(versionUrl, { - headers: { - "Authorization": `Bearer ${activeToken.iucnToken}` - } - }); - - return res.json({ - success: true, - connected: true, - apiVersion: "v4", - message: "IUCN API v4 is connected and responding" - }); - } catch (error: any) { - console.log("IUCN V4 API check failed:", error.message); - - // If token is invalid, return a useful message - if (error.response?.status === 401) { - return res.status(401).json({ - success: false, - connected: false, - message: "IUCN API v4 token is invalid. Please check your token and try again." - }); - } - - // For other errors, continue to try v3 - console.log("Falling back to IUCN v3 API check"); - } - } - // If no v4 token or v4 check failed, try v3 - const apiKey = process.env.IUCN_API_KEY; - if (!apiKey) { + if (!activeToken?.iucnToken) { return res.status(401).json({ success: false, connected: false, - message: "No IUCN API credentials found. Please add your IUCN API key." + message: "IUCN API v4 token is not configured. Please set your token in the API Token panel." }); } - + try { - // For v3, use a really simple request to avoid the 414 error - const response = await axios.get(`${IUCN_V3_BASE_URL}/version`, { - params: { token: apiKey } + // Check if the API is working by hitting the version endpoint + const response = await axios.get("https://apiv4.iucnredlist.org/api/v4/version", { + headers: { + "Authorization": `Bearer ${activeToken.iucnToken}` + } }); return res.json({ success: true, connected: true, - apiVersion: "v3", - message: "IUCN API v3 is connected and responding" + apiVersion: "v4", + message: "IUCN API v4 is connected and responding" }); } catch (error: any) { - // Handle v3 API errors - console.log("IUCN V3 API check failed:", error.message); + console.log("IUCN API check failed:", error.message); + // Return useful error messages if (error.response?.status === 401) { - return res.status(401).json({ - success: false, + return res.status(401).json({ + success: false, connected: false, - message: "IUCN API v3 key is invalid. Please check your environment variables." + message: "IUCN API v4 token is invalid. Please check your token and try again." }); } + // For network errors or other issues return res.status(error.response?.status || 500).json({ success: false, connected: false, @@ -405,72 +372,57 @@ export async function registerRoutes(app: Express): Promise { }); } - // To avoid 414 errors, we'll limit the name parameter to just the genus and species - // This will extract first two parts of scientific name (genus and species) + // Extract genus and species for v4 API const nameParts = String(name).split(' '); - const simplifiedName = nameParts.slice(0, 2).join(' '); const [genusName, speciesName] = nameParts; - // Try with v4 API first if we have a token + // Get IUCN token const activeToken = await storage.getActiveToken(); - if (activeToken?.iucnToken) { - try { - // Use the v4 API with scientific name endpoint - const response = await axios.get(`${IUCN_V4_BASE_URL}/taxa/scientific_name`, { - headers: { - "Authorization": `Bearer ${activeToken.iucnToken}` - }, - params: { - genus_name: genusName, - species_name: speciesName || "" - } - }); - - return res.json({ - success: true, - data: response.data, - apiVersion: "v4" - }); - } catch (error: any) { - console.log("IUCN V4 API species lookup failed, falling back to V3:", error.message); - // Continue to v3 fallback - } - } - - // Fallback to v3 API - const apiKey = process.env.IUCN_API_KEY; - if (!apiKey) { + if (!activeToken?.iucnToken) { return res.status(401).json({ success: false, - connected: false, - message: "IUCN API key is not configured" + message: "IUCN API v4 token is not configured. Please set your token in the API Token panel." }); } - + try { - const response = await axios.get(`${IUCN_V3_BASE_URL}/species/name/${encodeURIComponent(simplifiedName)}`, { - params: { token: apiKey } + // Use the v4 API with scientific name endpoint + const response = await axios.get("https://apiv4.iucnredlist.org/api/v4/taxa/scientific_name", { + headers: { + "Authorization": `Bearer ${activeToken.iucnToken}` + }, + params: { + genus_name: genusName, + species_name: speciesName || "" + } }); - res.json({ + return res.json({ success: true, data: response.data, - apiVersion: "v3" + apiVersion: "v4" }); - } catch (error) { - if (axios.isAxiosError(error) && error.response) { - return res.status(error.response.status).json({ - success: false, - message: error.response.data?.message || "Error from IUCN Red List API", - status: error.response.status + } catch (error: any) { + console.log("IUCN API species lookup failed:", error.message); + + if (error.response?.status === 401) { + return res.status(401).json({ + success: false, + message: "IUCN API v4 token is invalid. Please check your token and try again." }); } - throw error; + + return res.status(error.response?.status || 500).json({ + success: false, + message: error.response?.data?.message || "Error from IUCN Red List API: " + error.message, + status: error.response?.status + }); } } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); res.status(500).json({ success: false, - message: "Failed to retrieve IUCN species data" + message: "Failed to retrieve IUCN species data: " + errorMessage }); } });