smart-image-scraper-mcp 2.9.0 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smart-image-scraper-mcp",
3
- "version": "2.9.0",
3
+ "version": "2.9.1",
4
4
  "description": "全网智能图片抓取 MCP 服务器 - 支持 Bing/Google 图片搜索、验证和下载",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -79,6 +79,30 @@ export class Orchestrator {
79
79
  */
80
80
  async processKeywordLink(keyword, count, source, options = {}) {
81
81
  const startTime = Date.now();
82
+ const KEYWORD_TIMEOUT = 20000; // 单个关键词20秒超时
83
+
84
+ // 为单个关键词添加超时保护
85
+ const timeoutPromise = new Promise((_, reject) =>
86
+ setTimeout(() => reject(new Error(`关键词 "${keyword}" 处理超时(20秒)`)), KEYWORD_TIMEOUT)
87
+ );
88
+
89
+ try {
90
+ return await Promise.race([
91
+ this._processKeywordLinkInternal(keyword, count, source, options, startTime),
92
+ timeoutPromise
93
+ ]);
94
+ } catch (error) {
95
+ logger.error(`Process keyword error: ${keyword}`, { error: error.message });
96
+ return {
97
+ keyword,
98
+ success: false,
99
+ error: error.message,
100
+ duration: Date.now() - startTime,
101
+ };
102
+ }
103
+ }
104
+
105
+ async _processKeywordLinkInternal(keyword, count, source, options, startTime) {
82
106
  // 根据 quality 参数决定模式
83
107
  const qualityMode = options.quality || 'balanced';
84
108
  const fastMode = qualityMode === 'fast';
@@ -163,13 +187,7 @@ export class Orchestrator {
163
187
  duration: Date.now() - startTime,
164
188
  };
165
189
  } catch (error) {
166
- logger.error(`Process keyword error: ${keyword}`, { error: error.message });
167
- return {
168
- keyword,
169
- success: false,
170
- error: error.message,
171
- duration: Date.now() - startTime,
172
- };
190
+ throw error; // 抛出让外层处理
173
191
  }
174
192
  }
175
193
 
@@ -183,6 +201,30 @@ export class Orchestrator {
183
201
  */
184
202
  async processKeywordDownload(keyword, count, source, options = {}) {
185
203
  const startTime = Date.now();
204
+ const KEYWORD_TIMEOUT = 45000; // 下载模式45秒超时(比link模式长)
205
+
206
+ // 为单个关键词添加超时保护
207
+ const timeoutPromise = new Promise((_, reject) =>
208
+ setTimeout(() => reject(new Error(`关键词 "${keyword}" 下载超时(45秒)`)), KEYWORD_TIMEOUT)
209
+ );
210
+
211
+ try {
212
+ return await Promise.race([
213
+ this._processKeywordDownloadInternal(keyword, count, source, options, startTime),
214
+ timeoutPromise
215
+ ]);
216
+ } catch (error) {
217
+ logger.error(`Process keyword download error: ${keyword}`, { error: error.message });
218
+ return {
219
+ keyword,
220
+ success: false,
221
+ error: error.message,
222
+ duration: Date.now() - startTime,
223
+ };
224
+ }
225
+ }
226
+
227
+ async _processKeywordDownloadInternal(keyword, count, source, options, startTime) {
186
228
  // 根据 quality 参数决定模式(download 模式默认高质量)
187
229
  const qualityMode = options.quality || 'balanced';
188
230
  const prioritizeQuality = qualityMode !== 'fast';
@@ -292,13 +334,7 @@ export class Orchestrator {
292
334
  duration: Date.now() - startTime,
293
335
  };
294
336
  } catch (error) {
295
- logger.error(`Process keyword error: ${keyword}`, { error: error.message });
296
- return {
297
- keyword,
298
- success: false,
299
- error: error.message,
300
- duration: Date.now() - startTime,
301
- };
337
+ throw error; // 抛出让外层处理
302
338
  }
303
339
  }
304
340