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
This commit is contained in:
114
server/routes.ts
114
server/routes.ts
@ -304,17 +304,22 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// IUCN API Status check endpoint
|
// IUCN API Status check endpoint - v4 only
|
||||||
app.get("/api/iucn/status", async (req: Request, res: Response) => {
|
app.get("/api/iucn/status", async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
// Try V4 API first (with bearer token)
|
|
||||||
const activeToken = await storage.getActiveToken();
|
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, {
|
if (!activeToken?.iucnToken) {
|
||||||
|
return res.status(401).json({
|
||||||
|
success: false,
|
||||||
|
connected: false,
|
||||||
|
message: "IUCN API v4 token is not configured. Please set your token in the API Token panel."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check if the API is working by hitting the version endpoint
|
||||||
|
const response = await axios.get("https://apiv4.iucnredlist.org/api/v4/version", {
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": `Bearer ${activeToken.iucnToken}`
|
"Authorization": `Bearer ${activeToken.iucnToken}`
|
||||||
}
|
}
|
||||||
@ -327,9 +332,9 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
message: "IUCN API v4 is connected and responding"
|
message: "IUCN API v4 is connected and responding"
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log("IUCN V4 API check failed:", error.message);
|
console.log("IUCN API check failed:", error.message);
|
||||||
|
|
||||||
// If token is invalid, return a useful message
|
// Return useful error messages
|
||||||
if (error.response?.status === 401) {
|
if (error.response?.status === 401) {
|
||||||
return res.status(401).json({
|
return res.status(401).json({
|
||||||
success: false,
|
success: false,
|
||||||
@ -338,45 +343,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// For other errors, continue to try v3
|
// For network errors or other issues
|
||||||
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) {
|
|
||||||
return res.status(401).json({
|
|
||||||
success: false,
|
|
||||||
connected: false,
|
|
||||||
message: "No IUCN API credentials found. Please add your IUCN API key."
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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 }
|
|
||||||
});
|
|
||||||
|
|
||||||
return res.json({
|
|
||||||
success: true,
|
|
||||||
connected: true,
|
|
||||||
apiVersion: "v3",
|
|
||||||
message: "IUCN API v3 is connected and responding"
|
|
||||||
});
|
|
||||||
} catch (error: any) {
|
|
||||||
// Handle v3 API errors
|
|
||||||
console.log("IUCN V3 API check failed:", error.message);
|
|
||||||
|
|
||||||
if (error.response?.status === 401) {
|
|
||||||
return res.status(401).json({
|
|
||||||
success: false,
|
|
||||||
connected: false,
|
|
||||||
message: "IUCN API v3 key is invalid. Please check your environment variables."
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.status(error.response?.status || 500).json({
|
return res.status(error.response?.status || 500).json({
|
||||||
success: false,
|
success: false,
|
||||||
connected: false,
|
connected: false,
|
||||||
@ -405,18 +372,22 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// To avoid 414 errors, we'll limit the name parameter to just the genus and species
|
// Extract genus and species for v4 API
|
||||||
// This will extract first two parts of scientific name (genus and species)
|
|
||||||
const nameParts = String(name).split(' ');
|
const nameParts = String(name).split(' ');
|
||||||
const simplifiedName = nameParts.slice(0, 2).join(' ');
|
|
||||||
const [genusName, speciesName] = nameParts;
|
const [genusName, speciesName] = nameParts;
|
||||||
|
|
||||||
// Try with v4 API first if we have a token
|
// Get IUCN token
|
||||||
const activeToken = await storage.getActiveToken();
|
const activeToken = await storage.getActiveToken();
|
||||||
if (activeToken?.iucnToken) {
|
if (!activeToken?.iucnToken) {
|
||||||
|
return res.status(401).json({
|
||||||
|
success: false,
|
||||||
|
message: "IUCN API v4 token is not configured. Please set your token in the API Token panel."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Use the v4 API with scientific name endpoint
|
// Use the v4 API with scientific name endpoint
|
||||||
const response = await axios.get(`${IUCN_V4_BASE_URL}/taxa/scientific_name`, {
|
const response = await axios.get("https://apiv4.iucnredlist.org/api/v4/taxa/scientific_name", {
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": `Bearer ${activeToken.iucnToken}`
|
"Authorization": `Bearer ${activeToken.iucnToken}`
|
||||||
},
|
},
|
||||||
@ -432,45 +403,26 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
apiVersion: "v4"
|
apiVersion: "v4"
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log("IUCN V4 API species lookup failed, falling back to V3:", error.message);
|
console.log("IUCN API species lookup failed:", error.message);
|
||||||
// Continue to v3 fallback
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to v3 API
|
if (error.response?.status === 401) {
|
||||||
const apiKey = process.env.IUCN_API_KEY;
|
|
||||||
if (!apiKey) {
|
|
||||||
return res.status(401).json({
|
return res.status(401).json({
|
||||||
success: false,
|
success: false,
|
||||||
connected: false,
|
message: "IUCN API v4 token is invalid. Please check your token and try again."
|
||||||
message: "IUCN API key is not configured"
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return res.status(error.response?.status || 500).json({
|
||||||
const response = await axios.get(`${IUCN_V3_BASE_URL}/species/name/${encodeURIComponent(simplifiedName)}`, {
|
|
||||||
params: { token: apiKey }
|
|
||||||
});
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
data: response.data,
|
|
||||||
apiVersion: "v3"
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
if (axios.isAxiosError(error) && error.response) {
|
|
||||||
return res.status(error.response.status).json({
|
|
||||||
success: false,
|
success: false,
|
||||||
message: error.response.data?.message || "Error from IUCN Red List API",
|
message: error.response?.data?.message || "Error from IUCN Red List API: " + error.message,
|
||||||
status: error.response.status
|
status: error.response?.status
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Failed to retrieve IUCN species data"
|
message: "Failed to retrieve IUCN species data: " + errorMessage
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user