refactor(grok): 移除流式请求重试逻辑并简化错误处理
移除 generateContentStream 方法中的重试机制及相关辅助方法,将错误处理简化为仅处理认证错误。版本号更新至 2.11.7.1。
This commit is contained in:
parent
46038a5459
commit
807e3670b1
2 changed files with 9 additions and 66 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
2.11.7
|
2.11.7.1
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import logger from '../../utils/logger.js';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import * as https from 'https';
|
import * as https from 'https';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { MODEL_PROTOCOL_PREFIX, isRetryableNetworkError } from '../../utils/common.js';
|
import { MODEL_PROTOCOL_PREFIX } from '../../utils/common.js';
|
||||||
import { getProviderModels } from '../provider-models.js';
|
import { getProviderModels } from '../provider-models.js';
|
||||||
import { configureAxiosProxy, configureTLSSidecar } from '../../utils/proxy-utils.js';
|
import { configureAxiosProxy, configureTLSSidecar } from '../../utils/proxy-utils.js';
|
||||||
import { MODEL_PROVIDER } from '../../utils/common.js';
|
import { MODEL_PROVIDER } from '../../utils/common.js';
|
||||||
|
|
@ -85,34 +85,6 @@ export class GrokApiService {
|
||||||
this.lastSyncAt = null;
|
this.lastSyncAt = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMaxRequestRetries() {
|
|
||||||
const requestMaxRetries = Number.parseInt(this.config.REQUEST_MAX_RETRIES, 10);
|
|
||||||
if (Number.isFinite(requestMaxRetries) && requestMaxRetries > 0) {
|
|
||||||
return requestMaxRetries;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
classifyApiError(error) {
|
|
||||||
const status = error.response?.status;
|
|
||||||
const errorCode = error.code;
|
|
||||||
const errorMessage = error.message || '';
|
|
||||||
const isNetworkError = isRetryableNetworkError(error);
|
|
||||||
|
|
||||||
if (status === 401 || status === 403) {
|
|
||||||
error.shouldSwitchCredential = true;
|
|
||||||
error.message = 'Grok authentication failed (SSO token invalid or expired)';
|
|
||||||
} else if (isNetworkError) {
|
|
||||||
// Network jitter or request timeout should not immediately degrade account health.
|
|
||||||
// Let the upper retry layer switch credential without incrementing the provider error count.
|
|
||||||
error.shouldSwitchCredential = true;
|
|
||||||
error.skipErrorCount = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { status, errorCode, errorMessage, isNetworkError };
|
|
||||||
}
|
|
||||||
|
|
||||||
async setupNsfw() {
|
async setupNsfw() {
|
||||||
if (this.nsfwSetupDone) return;
|
if (this.nsfwSetupDone) return;
|
||||||
try {
|
try {
|
||||||
|
|
@ -509,11 +481,7 @@ export class GrokApiService {
|
||||||
try { return (await axios(axiosConfig)).data; } catch (error) { return null; }
|
try { return (await axios(axiosConfig)).data; } catch (error) { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
async * generateContentStream(model, requestBody, retryCount = 0) {
|
async * generateContentStream(model, requestBody) {
|
||||||
const maxRetries = this.getMaxRequestRetries();
|
|
||||||
const baseDelay = this.config.REQUEST_BASE_DELAY || 1000;
|
|
||||||
let hasYieldedData = false;
|
|
||||||
|
|
||||||
if (this.converter) {
|
if (this.converter) {
|
||||||
if (this.uuid) this.converter.setUuid(this.uuid);
|
if (this.uuid) this.converter.setUuid(this.uuid);
|
||||||
if (requestBody._requestBaseUrl) this.converter.setRequestBaseUrl(requestBody._requestBaseUrl);
|
if (requestBody._requestBaseUrl) this.converter.setRequestBaseUrl(requestBody._requestBaseUrl);
|
||||||
|
|
@ -630,42 +598,17 @@ export class GrokApiService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hasYieldedData = true;
|
|
||||||
yield json;
|
yield json;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
yield { result: { response: { isDone: true, responseId: lastResponseId, _requestBaseUrl: reqBaseUrl, _uuid: this.uuid } } };
|
yield { result: { response: { isDone: true, responseId: lastResponseId, _requestBaseUrl: reqBaseUrl, _uuid: this.uuid } } };
|
||||||
} catch (error) {
|
} catch (error) { this.handleApiError(error); }
|
||||||
const { status, errorCode, errorMessage, isNetworkError } = this.classifyApiError(error);
|
}
|
||||||
const canRetryInRequest = !hasYieldedData && retryCount < maxRetries;
|
|
||||||
|
|
||||||
if (status === 429 && canRetryInRequest) {
|
handleApiError(error) {
|
||||||
const delay = baseDelay * Math.pow(2, retryCount);
|
const status = error.response?.status;
|
||||||
logger.info(`[Grok API] Received 429 during stream. Retrying in ${delay}ms... (attempt ${retryCount + 1}/${maxRetries})`);
|
if (status === 401 || status === 403) { error.shouldSwitchCredential = true; error.message = 'Grok authentication failed (SSO token invalid or expired)'; }
|
||||||
await new Promise(resolve => setTimeout(resolve, delay));
|
throw error;
|
||||||
yield* this.generateContentStream(model, requestBody, retryCount + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status >= 500 && status < 600 && canRetryInRequest) {
|
|
||||||
const delay = baseDelay * Math.pow(2, retryCount);
|
|
||||||
logger.info(`[Grok API] Received ${status} server error during stream. Retrying in ${delay}ms... (attempt ${retryCount + 1}/${maxRetries})`);
|
|
||||||
await new Promise(resolve => setTimeout(resolve, delay));
|
|
||||||
yield* this.generateContentStream(model, requestBody, retryCount + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNetworkError && canRetryInRequest) {
|
|
||||||
const delay = baseDelay * Math.pow(2, retryCount);
|
|
||||||
const errorIdentifier = errorCode || errorMessage.substring(0, 50);
|
|
||||||
logger.info(`[Grok API] Network error (${errorIdentifier}) during stream. Retrying in ${delay}ms... (attempt ${retryCount + 1}/${maxRetries})`);
|
|
||||||
await new Promise(resolve => setTimeout(resolve, delay));
|
|
||||||
yield* this.generateContentStream(model, requestBody, retryCount + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async listModels() {
|
async listModels() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue