mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
fix: add timeout configuration to Ollama fetcher for remote connections
- Add 10-second timeout to axios requests in getOllamaModels() - Improve error handling for timeout scenarios with specific warning message - Update tests to verify timeout configuration is passed correctly - Add new test case for timeout error handling Fixes #5677: Ollama remote server connections now timeout gracefully instead of hanging indefinitely
This commit is contained in:
parent
62f97b917a
commit
a3fe162e75
2 changed files with 43 additions and 10 deletions
|
|
@ -109,10 +109,14 @@ describe("Ollama Fetcher", () => {
|
|||
const result = await getOllamaModels(baseUrl)
|
||||
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(1)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`, { timeout: 10000 })
|
||||
|
||||
expect(mockedAxios.post).toHaveBeenCalledTimes(1)
|
||||
expect(mockedAxios.post).toHaveBeenCalledWith(`${baseUrl}/api/show`, { model: modelName })
|
||||
expect(mockedAxios.post).toHaveBeenCalledWith(
|
||||
`${baseUrl}/api/show`,
|
||||
{ model: modelName },
|
||||
{ timeout: 10000 },
|
||||
)
|
||||
|
||||
expect(typeof result).toBe("object")
|
||||
expect(result).not.toBeInstanceOf(Array)
|
||||
|
|
@ -131,7 +135,7 @@ describe("Ollama Fetcher", () => {
|
|||
const result = await getOllamaModels(baseUrl)
|
||||
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(1)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`, { timeout: 10000 })
|
||||
expect(mockedAxios.post).not.toHaveBeenCalled()
|
||||
expect(result).toEqual({})
|
||||
})
|
||||
|
|
@ -147,7 +151,7 @@ describe("Ollama Fetcher", () => {
|
|||
const result = await getOllamaModels(baseUrl)
|
||||
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(1)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`, { timeout: 10000 })
|
||||
expect(mockedAxios.post).not.toHaveBeenCalled()
|
||||
expect(consoleInfoSpy).toHaveBeenCalledWith(`Failed connecting to Ollama at ${baseUrl}`)
|
||||
expect(result).toEqual({})
|
||||
|
|
@ -155,6 +159,25 @@ describe("Ollama Fetcher", () => {
|
|||
consoleInfoSpy.mockRestore() // Restore original console.info
|
||||
})
|
||||
|
||||
it("should log a warning message and return an empty object on timeout", async () => {
|
||||
const baseUrl = "http://localhost:11434"
|
||||
const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}) // Spy and suppress output
|
||||
|
||||
const timeoutError = new Error("timeout of 10000ms exceeded") as any
|
||||
timeoutError.code = "ECONNABORTED"
|
||||
mockedAxios.get.mockRejectedValueOnce(timeoutError)
|
||||
|
||||
const result = await getOllamaModels(baseUrl)
|
||||
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(1)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`, { timeout: 10000 })
|
||||
expect(mockedAxios.post).not.toHaveBeenCalled()
|
||||
expect(consoleWarnSpy).toHaveBeenCalledWith(`Connection to Ollama at ${baseUrl} timed out after 10 seconds`)
|
||||
expect(result).toEqual({})
|
||||
|
||||
consoleWarnSpy.mockRestore() // Restore original console.warn
|
||||
})
|
||||
|
||||
it("should handle models with null families field in API response", async () => {
|
||||
const baseUrl = "http://localhost:11434"
|
||||
const modelName = "test-model:latest"
|
||||
|
|
@ -205,10 +228,14 @@ describe("Ollama Fetcher", () => {
|
|||
const result = await getOllamaModels(baseUrl)
|
||||
|
||||
expect(mockedAxios.get).toHaveBeenCalledTimes(1)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`)
|
||||
expect(mockedAxios.get).toHaveBeenCalledWith(`${baseUrl}/api/tags`, { timeout: 10000 })
|
||||
|
||||
expect(mockedAxios.post).toHaveBeenCalledTimes(1)
|
||||
expect(mockedAxios.post).toHaveBeenCalledWith(`${baseUrl}/api/show`, { model: modelName })
|
||||
expect(mockedAxios.post).toHaveBeenCalledWith(
|
||||
`${baseUrl}/api/show`,
|
||||
{ model: modelName },
|
||||
{ timeout: 10000 },
|
||||
)
|
||||
|
||||
expect(typeof result).toBe("object")
|
||||
expect(result).not.toBeInstanceOf(Array)
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export async function getOllamaModels(baseUrl = "http://localhost:11434"): Promi
|
|||
return models
|
||||
}
|
||||
|
||||
const response = await axios.get<OllamaModelsResponse>(`${baseUrl}/api/tags`)
|
||||
const response = await axios.get<OllamaModelsResponse>(`${baseUrl}/api/tags`, { timeout: 10000 })
|
||||
const parsedResponse = OllamaModelsResponseSchema.safeParse(response.data)
|
||||
let modelInfoPromises = []
|
||||
|
||||
|
|
@ -73,9 +73,13 @@ export async function getOllamaModels(baseUrl = "http://localhost:11434"): Promi
|
|||
for (const ollamaModel of parsedResponse.data.models) {
|
||||
modelInfoPromises.push(
|
||||
axios
|
||||
.post<OllamaModelInfoResponse>(`${baseUrl}/api/show`, {
|
||||
model: ollamaModel.model,
|
||||
})
|
||||
.post<OllamaModelInfoResponse>(
|
||||
`${baseUrl}/api/show`,
|
||||
{
|
||||
model: ollamaModel.model,
|
||||
},
|
||||
{ timeout: 10000 },
|
||||
)
|
||||
.then((ollamaModelInfo) => {
|
||||
models[ollamaModel.name] = parseOllamaModel(ollamaModelInfo.data)
|
||||
}),
|
||||
|
|
@ -89,6 +93,8 @@ export async function getOllamaModels(baseUrl = "http://localhost:11434"): Promi
|
|||
} catch (error) {
|
||||
if (error.code === "ECONNREFUSED") {
|
||||
console.warn(`Failed connecting to Ollama at ${baseUrl}`)
|
||||
} else if (error.code === "ECONNABORTED" || error.message?.includes("timeout")) {
|
||||
console.warn(`Connection to Ollama at ${baseUrl} timed out after 10 seconds`)
|
||||
} else {
|
||||
console.error(
|
||||
`Error fetching Ollama models: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue