fix(websearch): improve error handling and response validation
This commit is contained in:
parent
581ad5fbda
commit
3491eec86b
@ -16,19 +16,35 @@ export default class SearxngProvider extends BaseWebSearchProvider {
|
|||||||
throw new Error('API host is required for SearxNG provider')
|
throw new Error('API host is required for SearxNG provider')
|
||||||
}
|
}
|
||||||
this.apiHost = provider.apiHost
|
this.apiHost = provider.apiHost
|
||||||
|
try {
|
||||||
this.searxng = new SearxngClient({ apiBaseUrl: this.apiHost })
|
this.searxng = new SearxngClient({ apiBaseUrl: this.apiHost })
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(
|
||||||
|
`Failed to initialize SearxNG client: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||||
|
)
|
||||||
|
}
|
||||||
this.initEngines().catch((err) => console.error('Failed to initialize SearxNG engines:', err))
|
this.initEngines().catch((err) => console.error('Failed to initialize SearxNG engines:', err))
|
||||||
}
|
}
|
||||||
|
|
||||||
private async initEngines(): Promise<void> {
|
private async initEngines(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`${this.apiHost}/config`, { timeout: 5000 })
|
console.log(`Initializing SearxNG with API host: ${this.apiHost}`)
|
||||||
|
const response = await axios.get(`${this.apiHost}/config`, {
|
||||||
|
timeout: 5000,
|
||||||
|
validateStatus: (status) => status === 200 // 仅接受 200 状态码
|
||||||
|
})
|
||||||
|
|
||||||
if (!response.data || !Array.isArray(response.data.engines)) {
|
if (!response.data) {
|
||||||
throw new Error('Invalid response format from SearxNG config endpoint')
|
throw new Error('Empty response from SearxNG config endpoint')
|
||||||
}
|
}
|
||||||
|
|
||||||
this.engines = response.data.engines
|
if (!Array.isArray(response.data.engines)) {
|
||||||
|
throw new Error('Invalid response format: "engines" property not found or not an array')
|
||||||
|
}
|
||||||
|
|
||||||
|
const allEngines = response.data.engines
|
||||||
|
console.log(`Found ${allEngines.length} total engines in SearxNG`)
|
||||||
|
|
||||||
|
this.engines = allEngines
|
||||||
.filter(
|
.filter(
|
||||||
(engine: { enabled: boolean; categories: string[]; name: string }) =>
|
(engine: { enabled: boolean; categories: string[]; name: string }) =>
|
||||||
engine.enabled &&
|
engine.enabled &&
|
||||||
@ -38,11 +54,17 @@ export default class SearxngProvider extends BaseWebSearchProvider {
|
|||||||
)
|
)
|
||||||
.map((engine) => engine.name)
|
.map((engine) => engine.name)
|
||||||
|
|
||||||
|
if (this.engines.length === 0) {
|
||||||
|
throw new Error('No enabled general web search engines found in SearxNG configuration')
|
||||||
|
}
|
||||||
|
|
||||||
this.isInitialized = true
|
this.isInitialized = true
|
||||||
console.log(`SearxNG initialized with ${this.engines.length} engines`)
|
console.log(`SearxNG initialized successfully with ${this.engines.length} engines: ${this.engines.join(', ')}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
this.isInitialized = false
|
||||||
|
|
||||||
console.error('Failed to fetch SearxNG engine configuration:', err)
|
console.error('Failed to fetch SearxNG engine configuration:', err)
|
||||||
this.engines = []
|
throw new Error(`Failed to initialize SearxNG: ${err}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,14 +79,6 @@ export default class SearxngProvider extends BaseWebSearchProvider {
|
|||||||
await this.initEngines().catch(() => {}) // Ignore errors
|
await this.initEngines().catch(() => {}) // Ignore errors
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果engines为空,直接返回空结果
|
|
||||||
if (this.engines.length === 0) {
|
|
||||||
return {
|
|
||||||
query: query,
|
|
||||||
results: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await this.searxng.search({
|
const result = await this.searxng.search({
|
||||||
query: query,
|
query: query,
|
||||||
engines: this.engines as any,
|
engines: this.engines as any,
|
||||||
@ -85,13 +99,9 @@ export default class SearxngProvider extends BaseWebSearchProvider {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
console.error('Search failed:', err)
|
console.error('Searxng search failed:', error)
|
||||||
// Return empty results instead of throwing to prevent UI crashes
|
throw new Error(`Search failed: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
||||||
return {
|
|
||||||
query: query,
|
|
||||||
results: []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,9 +95,7 @@ class WebSearchService {
|
|||||||
return await webSearchEngine.search(formattedQuery, maxResults, excludeDomains)
|
return await webSearchEngine.search(formattedQuery, maxResults, excludeDomains)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Search failed:', error)
|
console.error('Search failed:', error)
|
||||||
return {
|
throw new Error(`Search failed: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
||||||
results: []
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,9 +108,9 @@ class WebSearchService {
|
|||||||
public async checkSearch(provider: WebSearchProvider): Promise<{ valid: boolean; error?: any }> {
|
public async checkSearch(provider: WebSearchProvider): Promise<{ valid: boolean; error?: any }> {
|
||||||
try {
|
try {
|
||||||
const response = await this.search(provider, 'test query')
|
const response = await this.search(provider, 'test query')
|
||||||
|
console.log('Search response:', response)
|
||||||
// 优化的判断条件:检查结果是否有效且没有错误
|
// 优化的判断条件:检查结果是否有效且没有错误
|
||||||
return { valid: response.results.length > 0, error: undefined }
|
return { valid: response.results !== undefined, error: undefined }
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { valid: false, error }
|
return { valid: false, error }
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user