Ошибки
API LLMost использует стандартные коды состояния HTTP для указания на успех или неудачу запроса. В случае ошибки вы получите структурированный ответ с подробной информацией о проблеме.
Структура ответа об ошибке
Все ошибки возвращаются в следующем формате:
type ErrorResponse = {
error: {
code: number; // HTTP код состояния
message: string; // Описание ошибки
metadata?: Record<string, unknown>; // Дополнительная информация об ошибке
}
};Пример ответа об ошибке
{
"error": {
"code": 401,
"message": "Неверные учетные данные",
"metadata": {
"reason": "invalid_api_key"
}
}
}Коды ошибок HTTP
400 - Неверный запрос
Запрос содержит недопустимые параметры или неправильно сформирован.
Возможные причины:
- Отсутствуют обязательные параметры
- Неверный формат данных
- Проблемы с CORS (при запросах из браузера)
- Недопустимые значения параметров
{
"error": {
"code": 400,
"message": "Параметр 'model' является обязательным",
"metadata": {
"parameter": "model",
"provided": null
}
}
}Совет по отладке
При получении ошибки 400, проверьте:
- Все обязательные параметры присутствуют
- Форматирование JSON корректно
- Значения параметров находятся в допустимых диапазонах
- Заголовки Content-Type установлены правильно
401 - Неавторизован
Проблема с аутентификацией. API-ключ отсутствует, недействителен или истек.
Возможные причины:
- API-ключ не предоставлен
- API-ключ недействителен
- API-ключ был отозван
- Неправильный формат заголовка Authorization
{
"error": {
"code": 401,
"message": "Неверные учетные данные",
"metadata": {
"reason": "invalid_api_key"
}
}
}Решение:
- Проверьте, что API-ключ правильно установлен в заголовке
Authorization: Bearer ВАШ_КЛЮЧ - Создайте новый API-ключ на странице ключей
- Убедитесь, что в ключе нет лишних пробелов или символов
402 - Требуется оплата
Недостаточно кредитов на аккаунте для выполнения запроса.
{
"error": {
"code": 402,
"message": "Недостаточно кредитов на аккаунте",
"metadata": {
"balance": 0.00
}
}
}Решение:
- Пополните баланс на странице биллинга
- Проверьте лимиты расходов вашего API-ключа
403 - Запрещено
Запрос был заблокирован системой модерации или по другим причинам безопасности.
Ошибки модерации
Когда контент нарушает политику использования модели или провайдера:
{
"error": {
"code": 403,
"message": "Ваш запрос был отклонен в результате модерации нашей системы безопасности",
"metadata": {
"reasons": ["Обнаружен потенциально вредный контент"],
"flagged_input": "...",
"provider": "openai",
"model": "gpt-4"
}
}
}Поля метаданных:
reasons- Причины блокировки контентаflagged_input- Фрагмент заблокированного вводаprovider- Провайдер моделиmodel- Идентификатор модели
Политика модерации
Разные модели и провайдеры имеют разные политики модерации. Контент, заблокированный одной моделью, может быть принят другой.
408 - Истекло время ожидания
Запрос превысил максимально допустимое время выполнения.
{
"error": {
"code": 408,
"message": "Время ожидания запроса истекло",
"metadata": {
"timeout": "120s",
"elapsed": "125s"
}
}
}Решение:
- Попробуйте уменьшить
max_tokens - Упростите запрос
- Попробуйте другую модель
- Повторите запрос через некоторое время
429 - Слишком много запросов
Превышен лимит частоты запросов.
{
"error": {
"code": 429,
"message": "Превышен лимит частоты запросов",
"metadata": {
"retry_after": 60,
"limit": "100 requests per minute",
"reset_at": "2025-01-15T12:35:00Z"
}
}
}Решение:
- Внедрите экспоненциальную задержку при повторных попытках
- Проверьте поле
retry_afterдля оптимального времени повтора - Рассмотрите возможность кэширования ответов
- Распределите запросы равномерно во времени
Рекомендации по повторным попыткам
async function retryWithBackoff(fn: () => Promise<any>, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error: any) {
if (error.error?.code === 429) {
const delay = error.error.metadata?.retry_after ? error.error.metadata.retry_after * 1000 : Math.pow(2, i) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
throw new Error('Превышено максимальное количество повторных попыток');
}502 - Модель недоступна
Запрошенная модель временно недоступна.
{
"error": {
"code": 502,
"message": "Модель временно недоступна",
"metadata": {
"model": "openai/gpt-4o",
"provider": "openai",
"status": "down"
}
}
}Решение:
- Попробуйте другую модель того же провайдера
- Попробуйте аналогичную модель от другого провайдера
- Повторите запрос через несколько минут
- Проверьте страницу статуса для информации о работоспособности
503 - Нет доступных провайдеров
Ни один провайдер не может обработать запрос в данный момент.
{
"error": {
"code": 503,
"message": "Нет доступных провайдеров модели",
"metadata": {
"model": "openai/gpt-4o",
"attempted_providers": ["openai", "azure"]
}
}
}Решение:
- Подождите несколько минут и повторите попытку
- Попробуйте альтернативную модель
- Проверьте статус сервиса
Обработка ошибок при потоковой передаче
При использовании stream: true, ошибки обрабатываются по-разному в зависимости от того, когда они возникают.
Ошибки до начала потока
Если ошибка возникает до начала потоковой передачи, возвращается стандартный JSON с ошибкой:
{
"error": {
"code": 400,
"message": "Неверный параметр model"
}
}Ошибки во время потока
Если ошибка возникает во время потоковой передачи, она отправляется как событие Server-Sent Event (SSE):
// HTTP статус остается 200 OK
data: {
"id": "gen-xxxxx",
"choices": [{
"delta": { "content": "" },
"finish_reason": "error",
"error": {
"code": 500,
"message": "Ошибка провайдера во время генерации",
"metadata": {
"provider": "anthropic",
"raw_error": "Connection reset by peer"
}
}
}]
}Важно: HTTP-статус будет 200 OK, даже если произошла ошибка во время потока. Всегда проверяйте поле error в каждом чанке.
Пример обработки потоковых ошибок
const response = await fetch('https://llmost.ru/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer ВАШ_API_КЛЮЧ',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'openai/gpt-4o',
messages: [{ role: 'user', content: 'Привет!' }],
stream: true,
}),
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader!.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n').filter(line => line.trim().startsWith('data:'));
for (const line of lines) {
const data = line.replace('data: ', '');
if (data === '[DONE]') continue;
try {
const parsed = JSON.parse(data);
// Проверка на ошибки в потоке
if (parsed.choices?.[0]?.error) {
const error = parsed.choices[0].error;
console.error('Ошибка во время потока:', error.message);
// Обработка ошибки
break;
}
// Обработка контента
const content = parsed.choices?.[0]?.delta?.content;
if (content) {
process.stdout.write(content);
}
} catch (e) {
console.error('Ошибка парсинга SSE:', e);
}
}
}Ошибки провайдеров
Когда ошибка происходит на стороне провайдера модели, метаданные включают дополнительную информацию:
{
"error": {
"code": 500,
"message": "Ошибка провайдера",
"metadata": {
"provider": "anthropic",
"provider_error": {
"type": "overloaded_error",
"message": "Сервис перегружен, попробуйте позже"
},
"raw_response": "..."
}
}
}Поля метаданных провайдера:
provider- Имя провайдера (openai, anthropic, google и т.д.)provider_error- Структурированная ошибка от провайдераraw_response- Необработанный ответ провайдера (если доступен)
Лучшие практики обработки ошибок
1. Всегда проверяйте статус ответа
const response = await fetch('https://llmost.ru/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': 'Bearer ВАШ_API_КЛЮЧ',
'Content-Type': 'application/json',
},
body: JSON.stringify({ /* ... */ }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`API Error ${error.error.code}: ${error.error.message}`);
}
const data = await response.json();2. Обрабатывайте разные типы ошибок
try {
const completion = await generateCompletion(prompt);
return completion;
} catch (error: any) {
const code = error.error?.code;
switch (code) {
case 401:
// Проблема с аутентификацией
console.error('Проверьте ваш API-ключ');
break;
case 402:
// Недостаточно средств
console.error('Пополните баланс аккаунта');
break;
case 429:
// Rate limit
const retryAfter = error.error?.metadata?.retry_after || 60;
console.log(`Повтор через ${retryAfter} секунд`);
await sleep(retryAfter * 1000);
return generateCompletion(prompt); // Retry
case 502:
case 503:
// Временные проблемы с сервисом
console.log('Попробуйте альтернативную модель');
break;
default:
console.error('Неожиданная ошибка:', error.error?.message);
}
throw error;
}3. Логируйте метаданные ошибок
Метаданные содержат ценную информацию для отладки:
try {
const result = await apiCall();
} catch (error: any) {
console.error('API Error:', {
code: error.error?.code,
message: error.error?.message,
metadata: error.error?.metadata,
timestamp: new Date().toISOString(),
});
// Отправка в систему мониторинга
monitoringService.logError(error);
}4. Используйте повторные попытки с задержкой
async function callWithRetry<T>(
fn: () => Promise<T>,
options = { maxRetries: 3, baseDelay: 1000 }
): Promise<T> {
let lastError: any;
for (let attempt = 0; attempt < options.maxRetries; attempt++) {
try {
return await fn();
} catch (error: any) {
lastError = error;
const code = error.error?.code;
// Не повторяем для определенных ошибок
if ([400, 401, 403].includes(code)) {
throw error;
}
// Экспоненциальная задержка
const delay = options.baseDelay * Math.pow(2, attempt);
console.log(`Попытка ${attempt + 1} не удалась, повтор через ${delay}мс`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw lastError;
}
// Использование
const completion = await callWithRetry(() =>
fetch('https://llmost.ru/api/v1/chat/completions', {
method: 'POST',
headers: { /* ... */ },
body: JSON.stringify({ /* ... */ }),
}).then(r => r.json())
);5. Graceful degradation
Имейте запасные варианты на случай сбоев:
async function generateWithFallback(prompt: string) {
const models = [
'openai/gpt-4o',
'anthropic/claude-3.5-sonnet',
'google/gemini-pro',
];
for (const model of models) {
try {
return await generate(prompt, model);
} catch (error: any) {
console.warn(`Модель ${model} не удалась:`, error.error?.message);
// Пробуем следующую модель
continue;
}
}
throw new Error('Все модели недоступны');
}Типы TypeScript
// Для строгой типизации ошибок
interface LLMostError {
error: {
code: number;
message: string;
metadata?: {
// Метаданные модерации
reasons?: string[];
flagged_input?: string;
provider?: string;
model?: string;
// Метаданные rate limit
retry_after?: number;
limit?: string;
reset_at?: string;
// Метаданные провайдера
provider_error?: {
type: string;
message: string;
};
raw_response?: string;
// Общие метаданные
[key: string]: unknown;
};
};
}
// Защита типов
function isLLMostError(error: unknown): error is LLMostError {
return (
typeof error === 'object' &&
error !== null &&
'error' in error &&
typeof (error as any).error?.code === 'number'
);
}
// Использование
try {
const response = await fetch(/* ... */);
const data = await response.json();
if (isLLMostError(data)) {
// TypeScript теперь знает структуру ошибки
console.error(`Код ошибки: ${data.error.code}`);
console.error(`Сообщение: ${data.error.message}`);
if (data.error.metadata?.retry_after) {
console.log(`Повтор через: ${data.error.metadata.retry_after}с`);
}
}
} catch (e) {
// Обработка сетевых ошибок
}Следующие шаги
- Изучите Параметры API для правильной настройки запросов
- Посмотрите примеры Потоковой передачи для обработки потоков
- Ознакомьтесь с Аутентификацией для правильной настройки ключей