UNPKG

perplexity-mcp-server

Version:

A Perplexity API Model Context Protocol (MCP) server that unlocks Perplexity's search-augmented AI capabilities for LLM agents. Features robust error handling, secure input validation, and transparent reasoning with the showThinking parameter. Built with

60 lines (59 loc) 2.75 kB
/** * @fileoverview Provides a utility function to make fetch requests with a specified timeout. * @module src/utils/network/fetchWithTimeout */ import { logger } from "../internal/logger.js"; // Adjusted import path import { McpError, BaseErrorCode } from "../../types-global/errors.js"; /** * Fetches a resource with a specified timeout. * * @param url - The URL to fetch. * @param timeoutMs - The timeout duration in milliseconds. * @param context - The request context for logging. * @param options - Optional fetch options (RequestInit), excluding 'signal'. * @returns A promise that resolves to the Response object. * @throws {McpError} If the request times out or another fetch-related error occurs. */ export async function fetchWithTimeout(url, timeoutMs, context, options) { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeoutMs); const urlString = url.toString(); const operationDescription = `fetch ${options?.method || "GET"} ${urlString}`; logger.debug(`Attempting ${operationDescription} with ${timeoutMs}ms timeout.`, context); try { const response = await fetch(url, { ...options, signal: controller.signal, }); clearTimeout(timeoutId); logger.debug(`Successfully fetched ${urlString}. Status: ${response.status}`, context); return response; } catch (error) { clearTimeout(timeoutId); if (error instanceof Error && error.name === "AbortError") { logger.error(`${operationDescription} timed out after ${timeoutMs}ms.`, { ...context, errorSource: "FetchTimeout", }); throw new McpError(BaseErrorCode.TIMEOUT, `${operationDescription} timed out.`, { ...context, errorSource: "FetchTimeout" }); } // Log and re-throw other errors as McpError const errorMessage = error instanceof Error ? error.message : String(error); logger.error(`Network error during ${operationDescription}: ${errorMessage}`, { ...context, originalErrorName: error instanceof Error ? error.name : "UnknownError", errorSource: "FetchNetworkError", }); if (error instanceof McpError) { // If it's already an McpError, re-throw it throw error; } throw new McpError(BaseErrorCode.SERVICE_UNAVAILABLE, // Generic error for network/service issues `Network error during ${operationDescription}: ${errorMessage}`, { ...context, originalErrorName: error instanceof Error ? error.name : "UnknownError", errorSource: "FetchNetworkErrorWrapper", }); } }